A bit of clarity for IIS request queueing

Hi again,

After IIS7 and later IIS versions, there has been some changes on the way the requests are queued, especially when you use Integrated pipeline. This blog is a very good resource to understand these changes.

Even this is not a new thing, there may still be confusions around using performance counter values, especially, when performing load tests, to see if there are queued requests, after a certain load.

I have created a test scenario, to concretize these differences, and to show you how you can evaluate the change on that pipline mode. See the steps and conclusion below. 

Step-1: I have setup an application pool using Framework V4 and created a test ASP.NET script to work under that application pool.

 

Test script looks like below, and it blocks a worker thread for 40 seconds.. Just to keep the CLR worker threads busy. I took it as an application, under the application pool i have created on earlier step.

40SecRequest.aspx:

<%@ Page %>
<script language="C#" runat="server">
private void Page_Load(object sender, System.EventArgs e)
{ System.Threading.Thread.Sleep(40000); }
</script>
 

Step-2: After that, I have decreased the "MaxWorker" threads to only "2" (4 procs machine), to force the queueing up of the requests easily:

 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config (framework folder is defined with application pool settings.)

..

<system.web>

<processModel autoConfig="false"               
maxWorkerThreads = "2"
              
maxIoThreads = "2"
              
minWorkerThreads = "1"
              
minIoThreads = "1"
              
/>

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

..

And also I have changed the "maxConcurrentRequestsPerCPU" setting to "3", for "integrated pipeline" to decrease the maximum number of requests to be executed to "3*numberofCPUCores" :

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<system.web>
<applicationPool
maxConcurrentRequestsPerCPU="3"
maxConcurrentThreadsPerCPU="1"
requestQueueLimit="5000"
/>
..

Step-3 : After that I have used that tinyget to pump some requests to the application pool with following command:  

 c:\Utils>tinyget.exe -srv:localhost -uri:/ProcessModelChanged/40SecRequest.aspx -threads:40 -loop:1

Observation

On Integrated pipeline:        

  • We have "8" requests executing, which is calculated like "numberOfCpuCores * MaxWorkerThreads" = 8 (4 * 2) , on parallel.
  • For “ASP.Net Applications” and “ASP.NET apps” counters “Requests in the application queue" is zero. Because, In integrated pipeline we don’t have application level queues. That is why these counters are zero.
  • For “ASP.Net” category “Request queued” is displaying the number of queued requests.

 

 If I convert the application pool pipeline mode to "Classic pipeline" mode;

  • We have now, "7" requests executing on parallel, which is calculated with "(numberOfCpuCores * MaxWorkerThreads )-  minFreeThreads" formulla per this article. This calculation makes "7" (4*2-1) parallel requests getting executed.
  • For “ASP.Net Applications” and “ASP.NET apps” counters “Requests in the application queue is now functional , because we have application level queues.
  • Also For “ASP.Net” category “Request queued” is displaying the number of queued requests again.

 

 I hope this was useful for you,

Thanks,

Mert