Performance counters remain essential for maintaining optimal ASP.NET application performance under heavy production loads. While modern IIS versions have evolved, many enterprises still rely on IIS 6.0 for legacy applications, making proper counter selection and implementation crucial.
These counters provide the most valuable insights without significant overhead:
1. ASP.NET Applications:
- Requests/Sec
- Request Execution Time
- Requests In Application Queue
- Errors Total/Sec
2. Process:
- % Processor Time (for w3wp.exe)
- Private Bytes
- Handle Count
3. Memory:
- Available MBytes
- Pages/Sec
4. Web Service:
- Current Connections
- Bytes Sent/Sec
- Bytes Received/Sec
For reliable production monitoring:
// Sample PowerShell script to log counters continuously
$counters = @(
"\ASP.NET Applications(__Total__)\Requests/Sec",
"\Process(w3wp)\% Processor Time",
"\Memory\Available MBytes"
)
$logFile = "D:\PerfLogs\IIS_Perf_$(Get-Date -Format 'yyyyMMdd').csv"
Get-Counter -Counter $counters -SampleInterval 60 -Continuous |
Export-Counter -FileFormat CSV -Path $logFile -Force
When running under heavy load (500+ concurrent requests):
- Limit counters to 15-20 critical metrics
- Increase sampling interval to 30-60 seconds
- Use separate monitoring servers when possible
- Configure circular logging to prevent disk space issues
Example: Diagnosing memory leaks
// Query Private Bytes growth over time
typeperf "\Process(w3wp)\Private Bytes" -si 300 -o memory_log.txt
// Correlate with .NET CLR Memory counters
typeperf "\Process(w3wp)\# Bytes in all Heaps" -si 300 -o heaps_log.txt
When managing IIS 6.0 servers running ASP.NET applications, performance counters are essential diagnostic tools - but they come with overhead. In production environments with heavy loads, I recommend:
// Sample PowerShell to check current counter impact
Get-Counter -ListSet * | Where-Object {$_.CounterSetName -like "*ASP.NET*"} |
Select-Object CounterSetName, Description
These counters provide maximum insight with minimal overhead:
- ASP.NET Applications: Requests/Sec, Errors Total, Sessions Active
- ASP.NET: Request Execution Time, Request Wait Time
- Memory: Available MBytes, .NET CLR Memory bytes in all heaps
- Processor: % Processor Time (for w3wp.exe)
For production monitoring with minimal impact:
// C# code to consume performance counters efficiently
var processorCounter = new PerformanceCounter(
"Processor",
"% Processor Time",
"_Total");
var aspNetRequests = new PerformanceCounter(
"ASP.NET Applications",
"Requests/Sec",
"__Total__");
// Sample values with minimal overhead
float GetLightweightMetrics() {
return aspNetRequests.NextValue();
}
During peak loads:
- Disable non-essential counters (e.g., abandon session monitoring)
- Increase sampling intervals (from 1s to 15-30s)
- Use remote monitoring where possible
- Consider ETW tracing for deep diagnostics
For our high-traffic IIS 6.0 storefront running ASP.NET 2.0:
// Batch file to toggle counters during peak
@echo off
logman stop "ASP.NET_Trace" -ets
logman update trace "ASP.NET_Trace" -p {AFF081FE-0247-4275-9C4E-021F3DC1DA35} 0x2 -o c:\traces\aspnet.etl -ets
timeout /t 300
logman start "ASP.NET_Trace" -ets