Home > IIS Stories > ASP.NET Threads – Thread Parameters in IIS Worker Processes

ASP.NET Threads – Thread Parameters in IIS Worker Processes


This post is to help you to understand ASP.NET thread parameters, and describe definitions, how-to check & how-to edit. Thread Parameters of .NET Applications can be a different topic. The information here, doesn’t cover all .NET applications, such as BizTalk Server Host, or your custom .NET codes. The detailed parameters in this post are only for ASP.NET in IIS.

‘Tuning Thread Parameters’ can be a good topic to be discussed after this introduction. And, this post is not recommending you to change default values, but giving you ideas to manage the parameters.


ASP Thread Parameter (not ASP.NET)

Previously, in Win32 native codes, IIS was running ASP Applications, and its thread parameter is quite simple. IIS has a setting – ‘ASPProcessorThreadMax’, which is 25(per CPU) by default, defined in a IIS Metabase (metabase.xml in c:\windows\system32\inetsrv)

(Refer the above link to check more details of metabase property)

So, this means that if there’re 26 ‘Active Server Pages’ applications, those take very very long time to finish, then 25 ASP’s are running in worker threads, and 1 ASP should stay in a queue, called ‘ASP Request Queue’ very long time.

In other words, if IIS has 2 CPU’s, and 60 ASP’s to run forever, then 50(=25×2) ASP’s are being handled by worker threads, and the rest 10 ASP’s should stay in ‘ASP request queue’.

The above concept is very important. It helps you to understand how to monitor ASP Applications, and how to determine optimal number of worker threads. For example, if a performance counter – ‘Active Server Pages\Requests Queued’ counter indicates a non-zero value, it means there’re queued requests, that means every worker threads are busy.
It also means there’s a delay, and you may need to increase #threads, unless %CPU utilization is bad.

In summary, ASPProcessorThreadMax means ‘number of worker threads for ASP, per CPU, per worker process(w3wp)’.



In managed codes, such as ASP.NET Applications, it’s usually difficult to guess how many threads are working on the ASP.NET, or .NET applications. This article handles ‘ASP.NET’ threads, not ‘.NET Application’ threads, because it’s another story.

Before moving forward, it’s required to understand what threads mean, and what a process mean. There can be various definitions, depending on what you have seen. In this article, a process is more about IIS Worker Process, W3WP.exe, that includes & manages thread-pools.


A process is an isolated memory space, using virtual memory addresses, and it includes 1, or more threads, those are executed by Processors. A single processor runs one thread at a time, and that’s why thread parameters are usually multiplied by #CPU.

In W3WP process, you can assume that a thread is running one application, such as report.aspx. So, in order to run 2 ASP’s at a time, 2 processors need to run them in multiple threads – those are ‘Worker Threads’. (W3WP also has other types of threads)

So, if a worker process has many kind of applications to run, such as ASP(*.asp), ASP.NET(*.aspx), and Web Services(*.asmx), the status of threads will be as shown above. You can see that w3wp process runs 7 applications in 7 threads.

For more details of worker processes in IIS, you can refer


ASP.NET Threads

ASP.NET Applications, including web-services, are using thread-parameters as follows,

  • maxWorkerThreads
  • maxIoThreads
  • minWorkerThreads
  • minIoThreads
  • minFreeThreads
  • minLocalRequestFreeThreads

Since .NET Framework2.0, Auto-Config feature has been introduced, which seems it can configure any good values automatically for your ASP.NET applications. So, you can’t find the above thread parameters in machine.config file, although they’re being configured with default values.

If you open machine.config file in ‘C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG’, it only has,

  <processModel autoConfig="true" />

If you see actual values & details of thread parameters, you will find that ‘autoConfig’ is not a correct name,  ‘hideConfig’ is better one, it’s just to hide default values.


In most cases, tuning ASP.NET thread-parameters, is to adjust the followings, check the prameters with their default values(in IIS6, earlier version of .NET Framework 3.5 SP1),

  Default values Description


Threads to run ASPX applications


I/O threads among IIS related components


To handle remote requests(Web service). A free thread means idle thread here, which is ready to run


To handle local requests(Web service) in a worker process.


Number of connection for remote web services from local, this used to be 2 in the earlier version of .NET

The default thread parameters for ASP.NET in IIS6, IIS7, IIS7.5 & IIS8 are not same values among the versions, I’m going to list them in a next post about tuning ASP.NET thread parameters. This article is for understanding thread parameters

Refer the below picture, it’s for understanding parameters with their roles,



So, once you check default values of Auto-Config, you can find that it’s nothing but HideConfig(hided configurations), because there’s no automatic things happen. The values are from previous version of .NET framework, and they are just good values to start with.

I was confused. I have been confused by Auto-config setting for a long time, is because I thought Auto-config will do something more, such as optimizing automatically, and configuring to use recommended values,
(mentioned in the KB –http://support.microsoft.com/kb/821268,
Contention, poor performance, and deadlocks when you make Web service requests from ASP.NET applications)

Anyway, KB#821268 has very useful information to adjust thread parameters. However, it’s required to check the title of KB again,

Contention, poor performance, and deadlocks when you make Web service requests from ASP.NET applications

In many cases, you need a different article, because it’s more common that many people who runs ASP.NET site, don’t make web service requests’. In other words, the above KB article may not cover your ASP.NET Applications, although you have poor performance, & deadlock problems, unless your site calls Web Service requests for backend via HTTP.


Analysis of default values for ASP.NET threads

<Updated at Feb 27, 2013>
The followings are more appropriate for IIS6 in Windows 2003 & ASP.NET v2 to 3.5

One worker thread is to run an web application, such as ‘report.aspx’. And a default value of maxWorkerThreads in .NET Framework, is 20. So, it seems you have 20 worker threads to run ASP.NET applications, but you have less, to run ‘*.aspx’ applications.

Actual number of worker threads = maxWorkerThreads(20) – minFreeThreads(8)

So, if your IIS has 1 CPU, you have 12 worker threads to run ASPX applications. And this is why #minFreeThreads can’t be higher than #maxWorkerThreads. (If so, you will see an configuration error.)

To understand this clearly, more examples are required,

1) IIS has 4 CPU’s, and ‘machine.config’ has default values(autoConfig is ‘true’),

maxWorkerThreads, maxIOThreads = 80 (20×4)
minFreeThreads = 8
minLocalRequestFreeThreads = 4
maxconnection = 2

<Updated at Feb 27, 2013>

After applying service packs, and installing new versions of .NET, worker threads to run any type of applications(aspx, or asmx) are ‘12x#CPU’ by default(autoconfig=”true”)
For example, if you have 2 processors, the number of worker threads is 24. And, this is for both ‘ASPX’, and web service requests. It became simple.

With autoconfig=’true’, the default value of maxconnections is 12x#CPU. If IIS has 2 processors, it is 24 connections.


2) My server has 2 CPU’s, and 3 worker processes(w3wp.exe), how many worker threads?

Each worker process(w3wp.exe) has,

maxWorkerThreads, maxIOThreads = 40 (20×2)
minFreeThreads = 8
minLocalRequestFreeThreads = 4
maxconnection = 2

<Updated at Feb 27, 2013>

By default(autoconfig=”true”), worker threads to run any type of applications are ‘12x#CPU’.
So, this case, 12 x #CPU threads for each process.


3) So, what will happen, if I run a load test with default thread-parameters?

Assumptions :
IIS has 1 CPU, 1 W3WP(IIS worker process), default values(autoConfig = “true”)
The load-test,

. has only 1 ASP.NET(such as report.aspx),
. sends 6 requests/sec,
. It takes exactly 4 seconds per page, on average.
. %CPU utilization is very low enough.

Things will happen,

  • 1 second (After starting a load test) : 6 requests are in worker threads.
  • 2 seconds : 12 requests are in worker threads.
  • 3 seconds : 12 requests are in worker threads, and 6 requests are in the queue
  • 4 seconds :
    6 requests in worker threads, just finished. 6 requests in the queue can go to worker threads, and recent 6 requests are being queued

How to check the ASP.NET thread-parameters?

You need to know the version of .NET framework first.

In IIS6, open IIS Manager, select a web site to check, open property window of the site, and switch to [ASP.NET] tab to check its version.



In IIS7, open IIS Manager, select ‘Application Pools’, and select the application pool to check as shown below,


Click ‘Basic Settings’,



Once you find the version, go to ‘C:\WINDOWS\Microsoft.NET\Framework\v.x.x.xxx\config’ folder, corresponding to your .NET framework version (e.g : v2.0.50727).
for example, C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG

Open ‘machine.config’ file, and search <processModel> element, the default value is as follows,

    <processModel autoConfig="true" />

The above means ‘default values were hidden.’ Winking smile
If autoConfig is false, you can set customized values in machine.config.


How to change default values

You need to find <system.web> element in your machine.config first, copy and paste the below after changing values. Make sure autoConfig is set to ‘false’ to use configured values.

For your information, 20 threads per CPU is a good number to start with, and it’s not a small number, if all the threads are working without a blocking problem, or delayed from backend.

When you edit machine.config, you’re going to replace <processModel> element, add ‘<httpRuntime>’ elements, and add ‘<system.net>’ elements under ‘</system.web>’.
You need to be very careful not to break its XML structure. It’s good idea to create a backup first, by copying machine.config file to a safe location.



<processModel autoConfig="false"
maxWorkerThreads = "20"
maxIoThreads = "20"
minWorkerThreads = "1"
minIoThreads = "1"





<add address="*" maxconnection="2" />


Note : If you copy the above, and paste to your machine.config file, it can have a validation error because the above section includes formatted text. And before making any changes, create a copy of your current machine.config as a backup.

The following is an example, when you want to add more worker threads, and your ASP.NET applications don’t make web service calls to the backend.



<processModel autoConfig="false"
maxWorkerThreads = "50"
maxIoThreads = "50"
minWorkerThreads = "1"
minIoThreads = "1"




<add address="*" maxconnection="2" />



New ASP.NET Thread Parameters in IIS7.x (on Windows 2008, & Windows 2008 R2)

Instead of using paramters in machine.config, applicationPool parameters of aspnet.config file is newly introduced to tune number of worker threads, or throttle number of concurrent requests running. (Since .NET framework 3.5 SP1)

You can add the followings to he aspnet.config file in ‘C:\Windows\Microsoft.NET\Framework64\v2.0.50727’, or ‘C:\Windows\Microsoft.NET\Framework64\v4.0.30319’, depends on the version used. The below parameters don’t exist by default.




maxConcurrentRequestsPerCPU is to set #Requests to run concurrently, and affect #worker threads too, the parameters don’t exist in aspnet.config file by default. This is more preferred to be used, because IIS handles other resources, as well as .NET applications.

maxConcurrentThreadsPerCPU is to set #WorkerThreads to run .NET applications concurrently, and has a direct impact to set the threadpool size of ASP.NET. You can disable this by setting “0” value, and just utilize maxConcurrentRequestsPerCPU only.

The above parameters are both ASPX, and web services, which means they are not like maxWorkerThreads & minFreeThreads. So, you don’t need to set machine.config settings to adjust minFreeThreads parameters for calling web services to backend, anymore.

In Summary,

ASP.NET parameters in ASPNET.CONFIG file replace thread parameters in machine.config settings in IIS7.x or later. (For IIS6, it still uses machine.config file only).

After applying .NET Framework3.5 SP1, the new parameters can be applied .NET Framework v2 with ASP.NET 3.5. Surely, they can be applied for ASP.NET v4.

The new parameters still doesn’t manage ‘maxconnection’ in machine.config file. You still need to set the maxconnection setting in machine.config if required, as follows,


        <add address=”*” maxconnections=”100” />


For your information,

The settings of maxConcurrentRequestsPerCPU, maxConcurrentThreadsPerCPU can be configured in the registry too. I think using aspnet.config can be better choice, however, I’m introducing the registry keays, so you don’t need to be confused with many ways to do the same thing.

Registry Path (depends on .NET framework version that you use)

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0\ , or

maxConcurrentRequestsPerCPU (DWORD)
maxConcurrentThreadsPerCPU (DWORD)

You don’t need to set both values, and you can just set maxConcurrentRequestsPerCPU. maxConcurrentThreadsPerCPU was ignored during my test, when the both parameters were set with different numbers.

How to tune

Next post will be about ‘How to tune’, and this article does not try to recommend you to change default values as many as possible. They’re good values to start with, and proper for many of IIS servers.



httpRuntime Element

processModel Element


.NET Application Performance and Scalability

Tuning IIS – machine.config settings

ASP.NET Thread Usage on IIS 7.5, IIS 7.0, and IIS 6.0

Categories: IIS Stories
  1. 2013/03/05 at 10:30 pm

    really impressed! everything is very open and very clear explanation of issues. it contains truly information. your website is very useful. thanks for sharing. looking forward to more! lista de email lista de email lista de email lista de email lista de email


  2. Durai
    2013/04/15 at 7:32 pm

    Very Good Article. Thank you very much for posting this.


  3. 2014/04/15 at 6:55 pm

    very informative. Thanks.

    Have a look at this link also http://www.etechpulse.com/2014/04/aspnet-worker-process-iis-process-model.html


  4. 2014/10/04 at 2:27 am
  5. 2015/04/28 at 11:59 pm

    Excellent Article, Joon! Truly different style of explanation and very easy to follow.


  6. Youvan
    2017/12/18 at 9:19 pm

    If I have 24 Logical Processor out of which I am using 20 by Affinity settings.
    What should be the ideal values for below parametres :
    Note : App pool is .net 4.5 Classic


  7. 2018/07/24 at 3:00 am

    I am sure this post has touched all the internet users, its really really
    pleasant post on building up new blog.


  1. 2013/02/28 at 5:02 pm
  2. 2013/07/21 at 9:08 pm
  3. 2014/07/30 at 7:20 pm
  4. 2017/12/18 at 11:27 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: