Search code examples
performanceiisfastcgiiis-10

How do I configure IIS-10 and FastCGI for high concurrency?


Scenario: we have a php 7 web application using IIS10 via FastCGI. We did performance testing on our application and noticed a slowdown. We ruled out the database tier. We looked at the IIS server and, even under heavy load, when the app slows down dramatically, the resources are not strained... no CPU spikes no RAM spikes. Digging further we came to the conclusion that all the requests coming in are simply being queued. When some of requests take longer (for some very large reports that take 1-3 minutes) then every other request is being queued up waiting for the first ones to go through.

So, the question is: where do we look to increase the number of concurrent requests IIS can handle at one time?

I have found these settings, under FastCGI, but VERY little documentation. Can someone explain what these four settings do?

  • Instance MaxRequests
  • Max Instances
  • Queue Length
  • Rapid Fails PerMinute

enter image description here

Are there any other settings we should be looking at under DefaultAppPool?

  • Queue Length
  • Maximum Worker Processes
  • Recycling

enter image description here

UPDATE: A few things should be clarified for other who might search this:

  • a request in this context means one call from the browser to the IIS server
  • we used jmeter https://jmeter.apache.org/ to do some basic load testing
  • a request (for the sake of this context) from browser to IIS server will be processed like this: browser > DefaultAppPool worker process (this is defaulted to 1 in IIS look into web gardens if you want to increase this) > FastCGI instance (think of this as process threads, language is tricky and people on the web use threads/processes/instances interchangeably which can be confusing). FastCGI is defaulted to 4. So this means when 5 concurrent requests come through, they all get funneled through the 1 DefaultAppPool worker process and 4 of the 5 will be worked on concurrently by FastCGI and the 5th will be queued. We tested this: after an IIS restart there will be no w3wp.exe or php-cgi.exe processes running. When the 5 concurrent requests come in: w3wp.exe will get started and it will spawn 4 php-cgi.exe processes (check task manager)
  • to increase concurrency we set FastCGI "Max Instances" to 0 which allows IIS to decide how much it wants to handle based on resources available but you can also set it to a specific higher number. We tested this and I believe it to be accurate. You can see the w2wp.exe process and php-cgi.exe processes increasing in number as requests are coming in.
  • you should also be able to increase the DefaultAppPool worker processes, if you were to set this to 4 and leave the FastCGI instances to 4 as well that should mean, in theory, that each worker process would spawn its own 4 FastCGI instances for a total of 4x4=16 concurrent requests. I have not tested sufficiently to be sure 100% that that's how this actually plays out.

Solution

  • Instance MaxRequests: Controls the FastCGI process-recycling behavior. Specifies the maximum number of requests that a FastCGI application is allowed to handle before the process is recycled. The default value is 200.

    Max Instances: Specifies the maximum number of FastCGI processes to allow in the application process pool for the selected FastCGI application. This number also represents the maximum number of concurrent requests that the FastCGI application can handle. The default value is 4.

    Queue Length: Specifies the maximum number of requests that are queued for the FastCGI application pool. When the queue is full, subsequent requests return the HTTP error code 503 (Service Unavailable) to clients. This error code indicates that the application is too busy. The default value is 1000.

    Rapid Fails PerMinute: Specifies the maximum time allowed for a request to the application. If a FastCGI process takes longer than the specified time on a single request, it is terminated. The default value is 90 seconds.

    Application Pools:

    Queue Length: Indicates to HTTP.sys how many requests to queue for an application pool before rejecting future requests. The default value is 1000.

    Maximum Worker Processes: Indicates the maximum number of worker processes that would be used for the application pool.

    For the attributes in Recycling, you can refer to this link:

    https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools/add/recycling/