Home > IIS Stories > ASP.NET Threads–Tuning Thread Parameters (#1/2)

ASP.NET Threads–Tuning Thread Parameters (#1/2)

 

Pre-reading : ASP.NET Threads – Thread Parameters in IIS Worker Processes

https://fullsocrates.wordpress.com/2013/02/28/asp-net-threads-thread-parameters-in-iis-worker-processes-2/

…Tuning ASP.NET thread parameters is likely to reduce queued requests with its waiting time, and to increase running applications concurrently. By doing so, it can NOT reduce a latency(time-taken) for a single request, but it can increase concurrency, that means total throughtput, that increases number of completed requests within a given time….

ASP.NET Worker Threads

The default value of maxWorkerThreads is 12 per CPU. So, it can be 48 by maximum, if you have 4 processors in your IIS. When I deliver any trainings of IIS, usually, attendees have 2 kinds of questions on this, (1) when they should tune this, and (2) what’s a recommended setting on this. To move forward these questions, we need to start our discussion about ‘How-to-Monitor’ worker threads.

Once there’s a request from a client-browser, such as, ‘http://domain_name/report.aspx’, the ASP.NET application – report.aspx – will be handled by a worker thread in a worker process, w3wp.exe.
The worker process (aka. application pool) includes thread-pool, set of threads – ready to run incoming ASP.NET applications. So, a worker thread in W3WP, is going to run report.aspx until it’s completed, that means report.aspx will consume one worker thread for a while.

image

Basically, if IIS has a single processor, the actual number of worker threads for *.aspx(ASP.NET) is 12 by default, because of the following formula,

maxWorkerThreads(20x#CPU) – minFreeThreads(8) = 12

<updated note Feb 2013>
the above formula (20x#CPU – minFreeThreads) is valid when autoconfig is false in machine.config

 

Let’s try to understand parameters with an engineer’s way,

To understand the above numbers clearly, I’m going to show you a stress testing scenario,

(1) At first, I prepared an ASPx page, that takes 20 seconds to be completed,

<%@ Import Namespace="System.Threading" %>

<%
    Thread.Sleep(20000)
    Response.Write("20 seconds passed")
%>

I saved the above as ‘longtime.aspx’, and placed it at ‘c:\inetpub\wwwroot\demo’
So, if there’re many requests/second enough, there’ll be no available worker threads for them. For this case, the above code doesn’t cause high CPU utilization, and just designed to cause 20 seconds of delay.

(2) I created a new stress test project using VS2008(SP1), and set the below parameters,

: 50 concurrent users, testing duration : 10 minutes, keep sending requests without idle, or think time. Set a request – http://myservername/demo/longtime.aspx

(3) In my server, I added performance counters to monitor as follows,

  : ASP.NET Apps v2.x\Requests Executing
  : ASP.NET Apps v2.x\Requests in Application Queue

image

(4) Make sure IIS has default thread parameters in ‘machine.config file’ of the server,

machine.config is located in C:\Windows\Microsoft.NET\Framework64\v2.0.50727, in case of 64bit & ASP.NET v2.

 

(5) Started the stress test using VS2008, and monitor counters,

  : I checked my load test, and found that it’s sending about 20+ requests/sec.

 

(6) Reading Performance Counters

image

‘#Requests Executing’(blue line) was growing for a while, until it hits 12, and stopped being increased. Just after reaching ‘12’, ‘Requests in Application Queue’ started growing.
’Requests in Application Queue’(red) just keep growing during the test.

<update, Feb 2013>

‘Requests in Application Queue’ counter under ‘ASP.NET Apps vx.x’ object has been retired. It doesn’t show you any useful number anymore, because the application queue is not managed by new changed design of .NET framework. You may use ‘Requests Queued’ counter in ASP.NET vx.x’ object instead. ‘Requests in Application Queue’ counter only works fine in IIS6 with .NET v2.

According to the result, it tells you that #requests running can’t exceed 12, because actual #maxWorkerThreads is 12, and the following requests are being queued until there’s available threads to dispatch requests.

 

(7) Adjusting ASP.NET thread-parameters

image

I changed them as follows,

  : autoConfig = “true”, maxWorkerThreads = “40”, minFreeThreads = “15”

According to the formula, actual #worker threads = 40 – 15 = 25.

(8) Run the same load test, mentioned (2), and Reading Performance Counters

image

‘Requests Executing’(blue) was growing for a while, until it hits 25, and stopped being increased. Just after its reaching ‘25’, #requests in ‘App Queue’ started being increased.
’Requests in Application Queue’(red) just keep growing during the test, which means many of requests are staying in the queue without being handled in a worker thread.

More monitoring tips

IIS & .NET framework include useful performance counters to monitor system status. Here’re some basic counters to work with tuning thread parameters,

ASP.NET vx.x \ Requests Current
ASP.NET vx.x \ Requests Queued
ASP.NET Apps vx.x \ Requests Executing

If you have a single web application(A set of ASPx pages those share a same web.config, such as creating an application for a virtual directory in IIS manager) to test, you can use the below formula under testing condition,

Requests Current = Requests Executing + Requests Queued

For example, you sent 50 concurrent requests those take very long time, and a worker process has 12 threads per CPU(by default) with 2 processors, the situation will like the followings,

50  = 24(12×2, running) + 26(queued requests)

Tuning ASP.NET thread parameters is likely to reduce queued requests, and to increase running applications concurrently. By doing so, it can NOT reduce a latency(time-taken) for a single request, but increase concurrency, that means total throughtput, that increases number of completed requests within a given time.

For more information of using Performance monitor, you can refer,
Performance Monitoring Getting Started Guide
http://technet.microsoft.com/en-us/library/dd744567(v=ws.10).aspx 

In summary,

Without a concern for high CPU utilization, or memory pressure issues, if you have many long running applications with delays from backend systems, you can have better throughput by increasing #worker threads, in machine.config.

Using default values is not a bad idea for many cases, however, they’re not optimal numbers.

To adjust thread parameters, it’s required to understand how to monitor the status of ASP.NET applications, & IIS. This article introduced performance counters to be used. There’re more useful counters when you take a look avilable counters in perfmon.

In IIS7.x or later, parameters in aspnet.config are introduced, and it doesn’t require modifying machine.config file. This will be discussed in a next post.

================================================================

You may skip the below section, about WinDBG output,

FYI, for debugger(WinDBG) users,

During the worker process(w3wp) has 25 requests running, you may want to cross-check in WinDBG by attaching it to the current w3wp.exe, as follows,

image

: number of threads has been increased.

image

: there’re 25 worker threads running in the w3wp process.

All the worker threads are running ‘longtime.aspx’, and thread.sleep method,

image

================================================================

Categories: IIS Stories
  1. 2013/08/09 at 10:17 am

    Hi Joon Choi,

    First of all, thank you for such a beautiful and clear article.
    I got many of my concepts cleared here.
    But I was confused by one thing: in point 7, the screenshot says autoConfig=”false” while, the text says autoConfig=”true”
    I think it is autoConfig=”false” for sure, but I thought better ask then assume.

    Regards,
    Varun Shringarpure

    Like

    • 2013/09/02 at 12:13 pm

      yes, it should be set false as noted in the text, thanks for your comment, have a good day!

      Like

  2. Lamiae Bouananae
    2013/10/29 at 1:50 am

    Thank you for this nice article.
    We are facing a serious issue on one of our important events. On this event, a high number of concurrent users get connected to the web server. This causes a lot of request time out errors at the event viewer log. We notice a high increase in requests queued and requests wait time and request execution time. Do you think that the tuning tweaks that you described may solve that problem and enable the concurrency we see in these events

    Like

  3. 2014/02/08 at 7:39 pm

    Посмотрите на досуге http://ardiss.ru/o-nas/poleznaya-informacziya/stati-po-teme-stroitelstva/dolya-derevyannogo-domostroeniya возможно вы захотите себе его купить. А также: технология строительства домов из бруса видео, домокомплекты из бруса новосибирск, брусовой дом 9 9.

    Like

  1. 2013/02/28 at 5:02 pm
  2. 2013/08/25 at 10:33 pm
  3. 2020/12/31 at 3:07 am

Leave a comment