title: IIS 7.0 503 errors with generic handler (.ashx) implementing IHttpAsyncHandler
body: <p>I'm running into some performance issues using a generic handler that implements IHttpAsyncHandler. At its simplest, the handler receives a GET request, and 20 seconds later ends the response after writing '&lt; timeout / >' to the response.</p>
  
  <p>When hammering the .ashx with 10000-20000 simultaneous requests, it fails with 503 server unavailable after precisely 5000 requests. When switching to synchronous mode, and ending the request immediately, the problem goes away.</p>
  
  <p>I've tinkered with a number of settings, yet the only thing I've managed to acheive is lower the request threshold at which this error occurs.</p>
  
  <p>Here's a rundown of the settings I've toyed with:</p>
  
  <p><strong>machine.config:</strong></p>
  
  <pre><code>&lt;configuration&gt;
      ...
      &lt;system.web&gt;
          ...
          &lt;processModel enable="true" requestQueueLimit="10000"/&gt;
          ...
  </code></pre>
  
  <p><strong>web.config:</strong></p>
  
  <pre><code>&lt;configuration&gt;
      ...
      &lt;system.web&gt;
          ...
          &lt;httpRuntime enable="true" appRequestQueueLimit="10000"/&gt;
          ...
  </code></pre>
  
  <p><strong>IIS Manager > ApplicationPools > Advanced Settings</strong></p>
  
  <pre><code>Queue Length : 65535
  </code></pre>
  
  <p>Although I can't be sure, it seems like these settings work good and fine if the requests are synchronous, but when async, I can't seem to get beyond exactly 5000 requests before the server starts telling me to go away. If I set things lower (can't remember exactly which setting that would be from the above, but I've tried them all), then the 503 count goes up accordingly, but I can never stop it happening beyond 5000 when under serious load.</p>
  
  <p>It seems that there a a number of settings scattered in a myriad of places that might affect this, but the 5000 seems fairly set in stone. I see <a href="http://74.125.77.132/search?q=cache:Rw6hb12Ac94J:www.duringlunch.com/file.axd%3Ffile%3DAdvanced%2BASP.Net%2B2.ppt+appRequestQueueLimit+%22up+to%22+5000&amp;hl=en&amp;ct=clnk&amp;cd=1&amp;gl=uk&amp;client=firefox-a" rel="noreferrer">here</a> that appRequestQueueLimit cannot exceed 5000, but can find no further info about this, and wonder if this is misinformation.</p>
  
  <p>Is there any kind of "flood-control" setting in IIS that might be limiting a single host to no more than 5000 requests? How can I get IIS to handle more that 5000 concurrent asynchronous requests?</p>
  
  <p><strong>Edit2: Are there any counters or other indicators of which limit might be being exceeded, and how would I investigate further?</strong></p>
  
  <p>Edit: Here's the loadgenerator code:</p>
  
  <pre><code>using System;
  using System.Net;
  using System.Threading;
  
  namespace HammerTime
  {
      class Program
      {
          private static int counter = 0;
          static void Main(string[] args)
          {
              var limit = 5000;
              ServicePointManager.DefaultConnectionLimit=limit;
              for (int i = 0; i &lt; limit;++i )
              {
                  StartWebRequest(i.ToString());
  
              }
              Console.ReadLine();
          }
  
          private static void StartWebRequest(string channelId)
          {
              string uri = "http://spender2008/test/Test.ashx?channel="+channelId;
              HttpWebRequest request = (HttpWebRequest) WebRequest.Create(uri);
              request.BeginGetResponse(responseHandler, request);
          }
  
          private static void responseHandler(IAsyncResult ar)
          {
              try
              {
                  HttpWebRequest state = (HttpWebRequest)ar.AsyncState;
                  HttpWebResponse response = (HttpWebResponse)state.EndGetResponse(ar);
  
              }
              catch(Exception e)
              {
                  Console.WriteLine(e.Message);
              }
              finally
              {
                  Console.WriteLine(Interlocked.Increment(ref counter));
              }
  
          }
      }
  }
  </code></pre>