Microsoft IIS server

Tune the IIS server will help you to avoid some common errors and gain a better performance of Web applications. This section highlights the key performance settings of IIS. You can refer to the IIS Operation Guide for details on how to extensively tune IIS server.

Recommendations for avoiding common errors on IIS

IIS should be tuned to avoid the contention, poor performance, and deadlocks for the Web applications. Following are some samples of commons error that you may find in Application log, System log or even log in the Web browser.

  • Event Type: Error

    Event Source: ASP.NET

    Event ID: 1003

    Description: aspnet_wp.exe (PID: <xxx>) was recycled because it was suspected to be in a deadlocked state. It did not send any responses for pending requests in the last 180 seconds.

  • Event Type: Warning

    Event Source: W3SVC-WP

    Event ID: 2262

    Description: ISAPI 'C:\Windows\Microsoft.net\Framework\v.2.0.50727\aspnet_isapi.dll' reported itself as unhealthy for the following reason: 'Deadlock detected'.

  • Event Type: Warning

    Event Source: W3SVC

    Event ID: 1013

    Description: A process serving application pool 'DefaultAppPool' exceeded time limits during shut down. The process id was '<xxxx>'.

  • You may receive the exception error message: "System.InvalidOperationException: There were not enough free threads in the ThreadPool object to complete the operation."

  • In the browser, you may also receive the exception error message: "Request timed out".

To avoid such problems, you can configure ASP.NET according to the suggestions below so to best fit your situation and make the Web application perform better. Details on how to configure the ASP.NET can be found at Advanced thread settings.

  1. Limit the number of .NET requests that can execute at the same time to approximately 12 per CPU.

  2. Permit Web service callbacks to freely use threads in the ThreadPool.

  3. Select an appropriate value for the maxconnections parameter. Base your selection on the number of IP addresses and AppDomains that are used.

Advanced thread settings

The following settings are the most-Appeon-related settings in ASP.NET.

When you call an Appeon web application from IIS, you may experience contention, poor performance, and deadlocks. Clients may report that requests stop responding (or "hang") or take a very long time to execute.

This problem might occur because ASP.NET limits the number of worker threads and completion port threads that a call can use to execute requests. If there are not sufficient threads available, the request is queued until sufficient threads are free to make the request. Therefore, .Net will not execute more than following number of requests at the same time:

(maxWorkerThreads*number of CPUs)-minFreeThreads

Note: The minFreeThreads parameter and the minLocalRequestFreeThreads parameter are not implicitly multiplied by the number of CPUs.

maxWorkerThreads and maxIoThreads

.NET uses the following two configuration settings to limit the maximum number of worker threads and completion threads that are used:

<processModel maxWorkerThreads="20" maxIoThreads="20" />

The maxWorkerThreads parameter and the maxIoThreads parameter are implicitly multiplied by the number of CPUs, the default value of these two parameters are both 20. If for some reason your application is slow, perhaps waiting for external resources, you could try to increase the number of threads to a value less than 100. For example, if you have two processors, the maximum number of worker threads is the following: 2*maxWorkerThreads

minWorkerThreads

The setting determines how many worker threads may be made available immediately to service a remote request. By default, the minWorkerThreads parameter is not present in either the Web.config file or the Machine.config file at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG. You need to manually add the following line to make the setting work.

<processModel minWorkerThreads="1" />

Threads that are controlled by this setting can be created at a much faster rate than worker threads that are created in other ways. The default value for the minWorkerThreads parameter is 1. The setting is recommended to set in the following way.

minWorkerThreads = maxWorkerThreads / 2

Note: This setting is implicitly multiplied by the number of CPUs.

minFreeThreads and minLocalRequestFreeThreads

The two settings determine how many worker threads and completion port threads must be available to start a remote request or a local request:

<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8" />

The default value is 8. If there are not sufficient threads available, the request is queued until sufficient threads are free to make the request. Therefore, .NET will not execute more than the following number of requests at the same time:

(maxWorkerThreads*number of CPUs)-minFreeThreads

Note: The minFreeThreads parameter and the minLocalRequestFreeThreads parameter are not implicitly multiplied by the number of CPUs.

maxconnection

The maxconnection parameter determines how many connections can be made to a specific IP address. The parameter appears as follows:

<connectionManagement>
  <add address="*" maxconnection="2" />
  <add address="65.53.32.230" maxconnection="12" />
</connectionManagement>

The maxconnection parameter setting applies to the AppDomain level. By default, because this setting applies to the AppDomain level, you can create a maximum of two connections to a specific IP address from each AppDomain in your process.

execution Timeout

The setting limits the request execution time:

<httpRuntime executionTimeout="90" />

The default is 110 seconds.

Note: If you increase the value of the executionTimeout parameter, you may also have to modify the processModel responseDeadlockInterval parameter setting.

Recommended thread settings

For most applications, you can use and apply the recommended changes in the Machine.config file as below, which can be found at C:\WINDOWS\Microsoft.NET\Framework\v2.0.********\CONFIG:

  1. Set the values of the maxWorkerThreads parameter and the maxIoThreads parameter to 100.

  2. Set the value of the maxconnection parameter to 12*N (N is the number of CPUs that you have).

  3. Set the values of the minFreeThreads parameter to 22*N and the minLocalRequestFreeThreads parameter to 19*N.

  4. Set the value of minWorkerThreads to 50. Remember, minWorkerThreads is not in the configuration file by default. You must add it.

If you have hyperthreading enabled, you must use the number of logical CPUs instead of the number of physical CPUs.

Note: If you have a server with one processor, when you use this configuration, you can execute a maximum of 78 .NET requests at the same time because 100-22=78. Therefore, at least 22*N worker threads and 22*N completion port threads are available for other uses (such as for the Web service callbacks).

For example, if you have a server with four processors and hyperthreading enabled, then n=8 (=2*4). Based on these formulas, you would use the following values for the configuration settings that are mentioned in this section.

<system.web>
......
<processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
<httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152" />
......
</system.web>
......
<system.net>
......
<connectionManagement>
  <add address="[ProvideIPHere]" maxconnection="96" />
</connectionManagement>
......
</system.net>

Also, if you use this configuration, 12 connections are available per CPU per IP address for each AppDomain, and you can execute a maximum of 624 .NET requests at the same time because 8* 100 - 176= 624.