Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7905987
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T10:43:00+00:00 2026-06-03T10:43:00+00:00

I already know the answer to this, but wanted to share with the community

  • 0

I already know the answer to this, but wanted to share with the community since it is NOT documented from Microsoft.

The scenario: A surge of traffic hits your IIS 7.5 ASP.NET website, and you notice that requests start queuing up. The performance of the site slows to a crawl, yet you have plenty of CPU and RAM available.

This is the problem we saw recently with a site that made a bunch of internal web-service calls. An internal health check would start timing-out, which would cause this server to drop out of our cluster. (However, this server is the most powerful hardware of the bunch …)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T10:43:02+00:00Added an answer on June 3, 2026 at 10:43 am

    After searching around the internet, I found the following articles from Microsoft that relate to the problem:

    KB 821268: Contention, poor performance, and deadlocks when you make Web service requests from ASP.NET applications

    This article gives some great performance-tweaking tips, however it fails to mention some some VERY important ceilings that we ran in to.

    The solution for us was to modify our machine.config, and populate the following XML nodes:

    <system.web>
        <processModel autoConfig="false" maxWorkerThreads="xxx" maxIoThreads="xxx" minWorkerThreads="xxx" minIoThreads="xxx" requestQueueLimit="5000" responseDeadlockInterval="00:03:00"/>
        <httpRuntime minFreeThreads="xxx" minLocalRequestFreeThreads="xxx"/>
    </system.web>
    

    I purposefully set some of these numbers to “xxx” since they are dependent upon your hardware.

    From the KB article above, Microsoft suggests some equations for figuring out these values. However, they fail to mention that the MAXIMUM value for these numbers is the size of an INT, or 32767.

    So, the CORRECT equations for figuring these out are as follows:

    • maxWorkerThreads: 32767 / #Cores
      • In our case, we have a 24-core server. So, our maxWorkerThreads value is correctly set to: 1365. Any number that results in an integer LARGER than 32767, the server will set the maxWorkerThreads to 32767.
    • maxIoThreads: Same as maxWorkerThreads (32767 / #Cores)
    • minWorkerThreads: maxWorkerThreads / 2
      • This was a tricky one. If one exceeded an integer value LARGER than 32767 (and despite what the KB article says, this number IS multiplied by the number of cores you have), and unlike the “max” value, this defaults to the number of cores on your machine! In our case, this was getting set to 24 (because we set an arbitrarily high value for the min), and that was KILLING the performance on our server.
    • minIoThreads: Same as minWorkerThreads
    • minFreeThreads: 88 * #Cores (taken directly from the KB article)
    • minLocalRequestFreeThreads: 76 * #Cores (taken directly from the KB article)

    This solution is not for everyone, and should only be used if you meet the criteria in the KB article.

    Another tool we used in helping us diagnose this was an .ASPX page with no code-behind that we could throw out on any server (without resetting the Application Pool). This page uses reflection to tell you what is actually going on in the thread pool, and what the values of these settings render to on your server.

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <style>
        body { margin: 20pt; padding: 0pt; font-family: Verdana, "san-serif";}
        fieldset { border-radius: 5px; border: none; background-color: #fff; margin: 10pt;}
        fieldset.parent { background-color: #f0f0f0; }
        legend { font-size: 10pt; color: #888; margin: 5pt; }
    
        .ports div { padding: 10pt 0pt 0pt 0pt; clear: both; }
        .ports div:first-child { padding: 0pt; }
        .ports div div { padding: 0pt; clear: none; margin: 1pt; background-color: #eef; display: block; float: left; border: 5pt solid #eef; }
        .ports div div:first-child { border-top-left-radius: 5pt; border-bottom-left-radius: 5pt; background-color: #ccf; border-color: #ccf;}
        .ports div div:last-child { border-top-right-radius: 5pt; border-bottom-right-radius: 5pt; background-color: #ccf; border-color: #ccf; padding: 0pt 10pt 0pt 10pt; }
    </style>
    
    </head>
    <body>
    
    <%
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    
    int worker, workerMIN, workerMAX;
    int port, portMIN, portMAX;
    System.Threading.ThreadPool.GetAvailableThreads(out worker, out port);
    System.Threading.ThreadPool.GetMinThreads(out workerMIN, out portMIN);
    System.Threading.ThreadPool.GetMaxThreads(out workerMAX, out portMAX);
    
     %>
    
    <fieldset class="parent">
    <legend>Thread Information</legend>
    
    <fieldset>
        <legend>Worker Threads</legend>
        <div class="ports">
            <div>
                <div>Min: <%=workerMIN %></div>
                <div>Current: <%=workerMAX - worker %></div>
                <div>Max: <%=workerMAX %></div>
            </div>
        </div>
    </fieldset>
    
    <fieldset>
        <legend>Completion Port Threads</legend>
        <div class="ports">
            <div>
                <div>Min: <%=portMIN %></div>
                <div>Current: <%=portMAX - port %></div>
                <div>Max: <%=portMAX %></div>
            </div>
        </div>
    </fieldset>
    
    <fieldset>
        <legend>Request Queue Information</legend>
        <div class="ports">
    
    <%
    
    
    var fi = typeof(HttpRuntime).GetField("_theRuntime", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static).GetValue(null);
    var rq = typeof(HttpRuntime).GetField("_requestQueue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(fi);
    var fields = rq.GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    
    foreach (var field in fields)
    {
        string name = field.Name;
        string value = "";
    
        switch (name)
        {
            case "_localQueue":
            case "_externQueue":
                System.Collections.Queue queue = field.GetValue(rq) as System.Collections.Queue;
                value = queue.Count.ToString();
                break;
    
            default:
                value = field.GetValue(rq).ToString();
                break;
        }
    
        %>
            <div>
                <div><%=name %></div>
                <div><%=value %></div>
            </div>
        <%
        //Response.Write(string.Format("{0}={1}<br/>", name, value));
    }   
    
    %>
        </div>
    </fieldset>
    </fieldset>
    
    
    
    </body></html>
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I think I already know the answer to this but thought I would ask
I think I already know the answer to this one, but i hope maybe
I think i already know the answer to this, but i cannot find anything
I know that this has already been asked here but the answer (using a
I have a feeling I may already know the answer to this question, but
I think I might already know the answer to this one but I need
I think I already know the answer to this, but I'm currently working on
I'm afraid I already know the answer to this, but I'm checking with the
I think I may already know the answer to this, but here goes. I
I think I may know the answer to this question already, but I just

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.