Monitoring Threads

Applies To: Windows Server 2003, Windows Server 2003 with SP1

IIS 6.0 runs in a set of multithreaded processes designed for efficient scaling on uniprocessor and multiprocessor systems. Threads are the sequences of execution in each process that run the process code on the processor. In the IIS 6.0 process, there is no simple association between threads and connections or between threads and requests, nor is there an easily quantifiable relationship between the optimum number of threads in the process and the number of files served, the number of requests filled, or the number of connections maintained.

Because IIS 6.0 uses the worker thread model (rather than the simpler, thread-per-client model, which dedicates a thread to each connection or request), a pool of threads, known as the worker threads, is dedicated to accepting and monitoring all connections. This frees other threads to do the remaining work of the application, such as authenticating users; parsing client requests; locating, opening, and transmitting files; and managing internal data structures.

Even though you cannot associate individual threads with connections or requests, you can:

  • Count the number of threads in the IIS 6.0 process.

  • Measure the amount of processor time that each thread gets.

  • Associate the number of threads (and processor activity) with the number of current connections, number of files served, and other measures of server activity and performance.

Several tools — including Performance Logs and Alerts, Task Manager, and System Monitor — monitor or enumerate the threads in a process. Individual threads are difficult to monitor, especially if they frequently start and stop. Monitoring threads is also costly. Be sure to monitor the overhead of the process in which your tool runs (by monitoring the Process\% Processor Time counter), and subtract this from the overall processor time for the data that you collect.

Monitoring Threads and Context Switches

Table 6.21 lists the counters that monitor threads and context switches. You can add to this list any counters that you use to associate numbers of threads with performance, such as Web Service\Current Connections, Web Service\Bytes/sec, or Server\Logon/sec.

Table 6.21 Counters for Monitoring IIS 6.0 Threads

Object\Counter Value

Process (W3wp1)\Thread Count

The number of threads created by the process. This counter does not indicate which threads are busy and which are idle. It displays the last observed value, not an average.

Thread (W3wp1:Thread #)\% Processor Time

The percentage of processor time that each thread of the worker process is using.

Thread (W3wp1/Thread #)\Context Switches/sec

The rate of switches from one thread to another. Thread switches can occur either inside of a single process or across processes.

System\Context Switches/sec

The combined rate at which all processors on the computer are switched from one thread to another.

1 Monitor the W3wp instance if you are running your Web server in worker process isolation mode. If you are running your server in IIS 5.0 isolation mode, monitor either the Inetinfo instance (for in-process applications) or the Dllhost instance (for out-of-process applications).

Balancing threads against overall performance as measured by connections and requests can be difficult. Any time that you tune threads, follow up with overall performance monitoring to see whether performance increases or decreases.

You can chart the Process\Thread Count: W3wp value over time to see how many threads the worker process creates and how the number of threads varies. Then, observe the processor time for each thread in the process (Thread\% Processor Time: W3wp/Thread #) during periods of high, medium, and low server activity (as indicated by the other performance measures).

To determine if you need to adjust the thread count, compare the number of threads and the processor time for each thread in the process to the total processor time. If the threads are constantly busy, but are not fully using the processor time, you might improve performance by allowing more threads. However, if all the threads are busy and the processors are operating at close to their maximum capacity, it is best to distribute the load across more servers instead of increasing the number of threads.

Context switch counters are provided for the System and Thread objects. If you decide to increase the maximum size of any of the thread pools, it is important to monitor the counters for context switches. Context switches occur when a running thread voluntarily relinquishes the processor, is preempted by a higher priority ready thread, or switches between user mode and kernel mode to use an Executive or subsystem service. Switching to the subsystem process causes one context switch in the application thread; switching back causes another context switch in the subsystem thread.

Increasing the number of threads can increase the number of context switches to the point that performance decreases rather than increases. Ten thousand or more context switches per second is high. If you see numbers in that range, consider reducing the maximum thread pool size.

You should also observe the patterns of context switches over time, which indicate that the kernel has switched the processor from one thread to another. A large number of threads is likely to increase the number of context switches. Although they allow multiple threads to share the processor, context switches also interrupt the processor and might interfere with its performance, especially on multiprocessor computers.

Controlling processor affinity can improve performance by reducing the number of processor cache flushes as threads move from one processor to another. For example, you might be able to reduce cache flushes for dedicated servers by assigning processor affinity. However be aware that dedicating a program to a particular processor might prevent other program threads from migrating to the least-busy processor.

Monitoring Interrupts and Deferred Procedure Calls

You also need to monitor the counters for interrupts and deferred procedure calls (DPCs). Table 6.22 lists the counters to use.

Table 6.22 Counters to Monitor Interrupts and Deferred Procedure Calls

Object\Counter Value


The rate, in average number of interrupts in incidents per second, at which the processor received and serviced hardware interrupts. It does not include deferred procedure calls, which are counted separately.

Processor\% DPC Time

The percentage of time that the processor spent receiving and servicing deferred procedure calls during the sample interval. Deferred procedure calls are interrupts that run at a lower priority than standard interrupts.

The value of the Processor\Interrupts/sec counter is an indirect indicator of the activity of devices that generate interrupts, such as the system clock, the mouse, disk drivers, data communication lines, network adapters, and other peripheral devices. These devices normally interrupt the processor when they have completed a task or require attention, suspending normal thread execution. The system clock typically interrupts the processor every 10 milliseconds, creating a background of interrupt activity.

Use the Processor\Interrupts/sec and Processor\% DPC Time counters to determine how much time the processor is spending on interrupts and deferred procedure calls. These two factors can be another source of load on the processor. Client requests can be a major cause of interrupts and deferred procedure calls. Some new network adapters include interrupt moderation, which accumulates interrupts in a buffer when the level of interrupts becomes too high.

Optimizing Thread Values

By default, the IIS 6.0 process creates as many as four threads per processor. IIS 6.0 continually adjusts the number of threads in its process in response to server activity. For most systems, this tuning is sufficient to maintain the optimum number of threads, but you can change the maximum number of threads per processor if your system requires this. If the threads in the IIS 6.0 process appear to be overworked or underutilized, consider these tuning strategies:

  • If nearly all of the threads of the IIS 6.0 process are busy nearly all of the time, and the processors are at or near their maximum capacity, consider distributing the workload among more servers. You can also add processors.

  • If nearly all threads appear busy, but the processors are not always active, consider increasing the maximum number of threads per processor. Do not increase the maximum number of threads unless you have processors with excess capacity. More threads on the same number of processors cause more interrupts and context switches, and result in less processor time per thread.

To adjust the maximum number of threads in the IIS 6.0 service process, use a registry editor to add the MaxPoolThreads entry to the following registry path:



Do not edit the registry unless you have no alternative. The registry editor bypasses standard safeguards, allowing settings that can damage your system, or even require you to reinstall Windows. If you must edit the registry, back it up first and see Registry Reference.

The MaxPoolThreads entry is calculated in units of threads per processor. Do not set this value below 2 or above 20. You can try setting the MaxPoolThreads entry to a higher value if back-end latency is higher; set the entry to a lower value for applications that are CPU-intensive. Continue monitoring the system carefully to make sure that changing the number of threads allowed achieves the effect that you want.