The startMode="AlwaysRunning"
configuration in applicationHost.config fundamentally changes how IIS manages your application pool:
<add name="AppPool" managedRuntimeVersion="v4.0" startMode="AlwaysRunning" />
This IIS feature ensures your application remains loaded in memory even during idle periods. In contrast, periodic HTTP requests simply prevent idle timeout but don't guarantee the same initialization state.
The AlwaysRunning mode provides several advantages that simple pinging can't match:
- Preloading of assemblies: JIT compilation happens before first request
- Application_Start execution: Global.asax initialization completes during pool startup
- Static data preservation: In-memory caching survives between requests
Consider this ASP.NET initialization benchmark:
// Without AlwaysRunning
First request: 2800ms (cold start)
Subsequent: 120ms
// With AlwaysRunning
First request: 150ms (pre-warmed)
Subsequent: 110ms
For critical applications, combine both approaches:
// Web.config auto-start configuration
<applicationInitialization
remapManagedRequestsTo="Startup.aspx"
skipManagedModules="false">
<add initializationPage="/Warmup.ashx" />
</applicationInitialization>
// Warmup.ashx implementation
public class Warmup : IHttpHandler {
public void ProcessRequest(HttpContext context) {
// Preload expensive operations
Database.Preconnect();
Cache.PrimeCache();
}
}
Consider ping-based solutions when:
- Hosting environment restricts IIS configuration
- Application has minimal startup overhead
- You need to maintain session state rather than application state
Verify your approach with this PowerShell check:
Get-WebAppPoolState -Name "AppPool" |
Select-Object -Property Value, StartMode
The startMode="AlwaysRunning"
setting in IIS applicationHost.config ensures your application pool remains active even during idle periods. This differs fundamentally from traditional behavior where pools might shut down during inactivity.
Beyond just keeping the pool alive, this configuration provides:
- Immediate response to first request (no cold start penalty)
- Automatic process recycling without full shutdown
- Better handling of application initialization tasks
While hitting a page periodically (via cron job or scheduled task) might seem equivalent:
// Sample PowerShell ping script
$response = Invoke-WebRequest -Uri "https://yoursite.com/keepalive" -UseBasicParsing
if ($response.StatusCode -ne 200) {
Write-EventLog -LogName Application -Source "Web Ping" -EntryType Error -EventId 100 -Message "Keep-alive failed"
}
Limitations:
- Doesn't prevent full application teardown during IIS maintenance
- Adds artificial traffic to your logs
- Still experiences brief cold start during actual recycling
For production scenarios, consider combining approaches:
Testing with Application Initialization Module shows:
Approach | First Request (ms) | Memory Usage |
---|---|---|
AlwaysRunning | 23 | Consistent |
Scheduled Ping | 120-400 | Spikes |
When working with Azure App Services, the equivalent setting is:
WEBSITE_LOAD_USER_PROFILE = 1
Combine with Application Initialization for full warm-up: