Diagnosing and Resolving IIS 7.5/ASP.NET 4.0 SendResponse Stalls in High-Availability Environments


5 views

When requests get stuck in IIS's SendResponse state, we're typically looking at one of three core issues:

  1. Network-level transmission delays
  2. Application-level response processing
  3. IIS/ASP.NET pipeline interference

First, let's verify some often-overlooked network settings:

netsh int tcp show global
netsh interface ipv4 show subinterfaces

Key settings to check:

  • Receive Window Auto-Tuning should be "normal"
  • ECN capability should be disabled
  • RSS (Receive Side Scaling) should be enabled

Even with autoConfig, we might need explicit thread pool settings in machine.config:

<system.web>
  <processModel 
    autoConfig="false"
    maxWorkerThreads="100" 
    maxIoThreads="100" 
    minWorkerThreads="50"
    minIoThreads="20"/>
</system.web>

Add this to applicationHost.config to verify caching behavior:

<system.webServer>
  <caching enabled="true" enableKernelCache="true">
    <profiles>
      <add extension=".aspx" policy="CacheUntilChange"/>
    </profiles>
  </caching>
</system.webServer>

Create a custom ETW trace to catch SendResponse delays:

logman create trace IIS_SendResponse -ow -o c:\traces\iis_sendresponse.etl -p {0811c1af-7a07-4a06-82ed-869455cdf713} 0xffffffff -nb 16 16 -bs 1024 -ft 1 -ets

For dynamic content that can be cached, implement output caching:

// In Global.asax
protected void Application_BeginRequest()
{
    if (Request.Url.AbsolutePath.EndsWith(".aspx"))
    {
        Response.Cache.SetCacheability(HttpCacheability.Server);
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
        Response.Cache.SetValidUntilExpires(true);
    }
}

When all else fails, these advanced checks often reveal the culprit:

  • Run appcmd list wp to check worker process health
  • Verify ARR (Application Request Routing) settings if configured
  • Check for SSL/TLS renegotiation delays
  • Monitor with PerfView for CLR stalls

When requests mysteriously hang during the SendResponse phase in IIS 7.5/ASP.NET 4.0 environments, even on robust infrastructure, we're typically dealing with one of these underlying issues:

// Sample PowerShell to monitor stuck requests
Get-WebRequest -State "SendResponse" | 
Where-Object { $_.TimeElapsed -gt 20000 } | 
Format-Table -Property TimeElapsed, Url, ClientIP

Despite disabling TCP offloading, we need deeper network diagnostics:

  • Check for NIC driver compatibility issues (particularly with virtualization)
  • Validate RSS (Receive Side Scaling) configuration
  • Monitor TCP retransmits with netstat -s

The integrated pipeline introduces subtle threading behaviors that aren't always apparent:

// Recommended thread configuration for high-throughput scenarios
<system.web>
  <processModel autoConfig="false" 
    maxWorkerThreads="100" 
    maxIoThreads="100" 
    minWorkerThreads="50" 
    minIoThreads="50"/>
</system.web>

Hyper-V virtual machines require additional scrutiny:

  • Check for VMQ (Virtual Machine Queue) conflicts
  • Validate synthetic vs. legacy network adapter usage
  • Monitor for host-level resource contention

Beyond appcmd, we need deeper instrumentation:

# ETW tracing for HTTP.sys and IIS
logman start IIS_Trace -p Microsoft-Windows-HttpService 0xFFFF -o trace.etl -ets
# Reproduce issue
logman stop IIS_Trace -ets

Even with low CPU usage, watch for:

  • Private bytes accumulation
  • Gen 2 garbage collection frequency
  • AppDomain recycling events

Despite fast SAN connectivity, consider:

  • MPIO policy configuration (failover vs. round robin)
  • Storage latency spikes during backup windows
  • Virtual disk fragmentation

Immediate actions while investigating:

// web.config tweaks for transient issues
<system.webServer>
  <serverRuntime enabled="true" 
    frequentHitThreshold="1" 
    frequentHitTimePeriod="00:00:10"/>
</system.webServer>