In IIS 6.0, incoming client requests are handled by the kernel-mode HTTP.sys driver. Previous IIS versions used the user-mode Winsock driver, but IIS 6.0 enhances performance by using the kernel-mode HTTP.sys driver. Kernel-mode drivers are more efficient than user-mode drivers because they provide direct access to the internal system resources. On the other hand, user-mode drivers are less efficient but provide much better stability and security since they can only access the user address space. In IIS 6.0, the kernel-mode HTTP.sys driver enhances performance in the areas of request routing, request queuing, and request caching.
HTTP.sys Routing and Queuing
Higher performance is achieved when a request is passed directly between a kernel-mode process and a user-mode process than when a request is passed between two user-mode processes. HTTP.sys accomplishes this by playing a kernel-level proxy role between incoming client requests and user-mode worker processes.
Worker processes are responsible for the actual processing of client requests. When you write an ASP.NET application, the application is hosted within a user-mode worker process (or processes if you are running a web garden). This worker process has a large pool of worker threads that can respond to HTTP.sys requests. If all the threads within the worker process’s thread pool are in use, HTTP.sys’s kernel-level queue will be utilized to temporarily hold requests until a thread becomes available. Heavy I/O activity is a common cause of worker thread pool depletion. To explain this situation it is important to understand that the worker process also has a pool of I/O threads that are used to accomplish I/O operations such as file, web service, or database access. Worker threads can get held up if they are waiting for I/O threads to finish processing heavy I/O operations. This lack of worker threads will cause request queuing by HTTP.sys to kick in. By the way, the HTTP.sys request queue can fill up making IIS respond back with 503 Server Not Available errors until threads become available once again.
To put it all together, when a new client request comes in and there are no available worker threads, HTTP.sys places the request in its kernel-level request queue. This queue is tied to the application pool that is assigned to your ASP.NET application. When a worker thread becomes available within the application pool's worker process(es), it pulls the request from the request queue and processes it. When the worker process has completed processing the request, it utilizes HTTP.sys to respond back to the requesting client and returns the worker thread back into the thread pool.
A noteworthy benefit of worker processes being user-mode rather than kernel-mode can be seen in how instability is handled. If an application hosted within a user-mode worker process crashes, requests are queued at the kernel level by HTTP.sys. The server simply hands out a new worker process, and the queued requests continue to be processed. Also, having worker processes run in user-mode protects the kernel from corruption and/or security violations that may be inherent to the ASP.NET application.
HTTP.sys Caching
Enhanced performance can also be seen in HTTP.sys’s ability to cache request responses. This ability makes it possible for HTTP.sys to respond to requests directly and efficiently by not having to interact with the user-mode worker process when a particular request has already been handled and cached.