Real-Time Diagnostics for .NET Runtime, ASP.NET Core, EF Core, Networking & More
1. Introduction to dotnet-counters
dotnet-counters is a cross-platform performance monitoring tool for .NET applications. It provides real-time metrics about the .NET runtime and your application without requiring any code changes or stopping the app.
It is part of the .NET Diagnostic Tools suite.
It enables developers, performance engineers, and SREs to understand:
- CPU usage
- Memory allocations
- GC behavior
- ThreadPool health
- ASP.NET Core traffic
- Kestrel server load
- System.Net outbound connections
- EF Core queries & DB activity
- Lock contention
- Process working set
- Request rates
- Connection counts
- And MUCH more
2. What is dotnet-counters? (Definition)
dotnet-counters is a lightweight CLI utility that subscribes to runtime performance metrics exposed by:
A. EventCounters (classic counters)
Used by:
- System.Runtime
- Microsoft.AspNetCore.Hosting
- Microsoft-AspNetCore-Server-Kestrel
- Microsoft.AspNetCore.Http.Connections
- System.Net.Http
- Microsoft.EntityFrameworkCore (legacy events)
B. System.Diagnostics.Metrics (new .NET metrics API)
Used by:
- ASP.NET Core built-in metrics
- EF Core built-in metrics
- System.Net
- .NET Runtime metrics
- Custom application metrics
The tool displays these counters live or records them to a file.
3. Why dotnet-counters exists (Purpose)
Before dotnet-counters, diagnosing .NET performance issues required:
- Attaching heavyweight profilers
- Installing Visual Studio Diagnostics
- Using Windows-only tools
- Waiting for dumps or logs
These methods were slow, disruptive, and risky for production.
Modern .NET apps run on:
- Linux containers
- Kubernetes
- Cloud VMs
- Azure App Service
- AWS ECS/EKS
- Docker
What developers need is a safe, fast, cross-platform way to monitor live performance.
dotnet-counters solves this.
4. When to Use dotnet-counters
Use dotnet-counters when you need:
✔ Live performance monitoring
✔ Realtime GC insight
✔ See allocations immediately
✔ Detect memory leaks
✔ Detect CPU spikes
✔ View RPS (requests/sec)
✔ Investigate latency & saturation
✔ Observe EF Core query load
✔ Analyze Kestrel traffic
✔ Identify contention issues
✔ Understand warm-up behavior
✔ Inspect ThreadPool starvation
✔ Debug production without restarts
✔ Monitor cloud workloads
You use it in:
- Local development
- Performance testing
- Load testing (JMeter, K6, Locust)
- Staging / UAT
- Production (safe)
- Kubernetes clusters
- Docker containers
- Azure/AWS troubleshooting
5. Installing dotnet-counters
It’s included with the .NET SDK.
Check version:
dotnet-counters --version
If not installed:
dotnet tool install -g dotnet-counters
6. dotnet-counters Commands Overview
dotnet-counters
You get:
| Command | Purpose |
|---|---|
| monitor | LIVE real-time metrics |
| collect | Record metrics to a file (offline analysis) |
| list | Show available counter providers |
| ps | List running .NET processes |
7. Listing .NET Processes
dotnet-counters ps
Shows:
1234 MyApp.Web
5678 WorkerService
Code language: CSS (css)
8. Showing Available Counters
dotnet-counters list
Code language: PHP (php)
Now returns a pointer to documentation:
➡ https://learn.microsoft.com/dotnet/core/diagnostics/available-counters
(This is your main EventCounters reference.)
9. Monitoring an App in Real Time (monitor)
Basic usage:
dotnet-counters monitor -p <PID>
Code language: HTML, XML (xml)
With specific providers:
dotnet-counters monitor -p <PID> System.Runtime Microsoft.AspNetCore.Hosting
Code language: CSS (css)
Your full example:
dotnet-counters monitor -p 30420 System.Runtime Microsoft.AspNetCore.Hosting Microsoft-AspNetCore-Server-Kestrel Microsoft.AspNetCore.Http.Connections System.Net.Http Microsoft.EntityFrameworkCore
Code language: CSS (css)
Press:
- p → pause
- r → resume
- q → quit
10. Recording Metrics to a File (collect)
dotnet-counters collect -p <PID> -o output.json
Code language: HTML, XML (xml)
Useful for:
- Long-running captures
- Production debugging
- Attaching to Jira tickets
11. Providers & Metrics (Deep Dive)
The BIG section — covers EVERY provider you need.
11.1 System.Runtime Counters
Source:
https://learn.microsoft.com/dotnet/core/diagnostics/available-counters
Key Metrics:
| Metric | Meaning |
|---|---|
| CPU Usage (%) | CPU used by the process |
| Allocation Rate | Bytes allocated/sec |
| GC Heap Size | Managed heap usage |
| GC Committed Bytes | Memory reserved by GC |
| % Time in GC | How much the app is paused for GC |
| Time paused by GC | Actual GC stop-the-world pause time |
| Gen 0/1/2 GC Count | Garbage collections |
| Working Set | Total memory consumption |
| Exception Count | Throw rate |
| ThreadPool Thread Count | Current pool size |
| ThreadPool Queue Length | Pending work items |
| Lock Contention Count | Locking issues |
| JIT Bytes | IL compiled |
| Methods Jitted | Total jitted methods |
| Active Timers | Timers currently alive |
This is the heart of your diagnostics.
11.2 ASP.NET Core Hosting Metrics
Source:
https://learn.microsoft.com/en-us/aspnet/core/log-mon/metrics/built-in
Counters include:
requests-per-secondcurrent-requestsfailed-requeststotal-requestsrequest-duration
11.3 Kestrel Server Metrics
Source:
https://learn.microsoft.com/dotnet/core/diagnostics/available-counters
Includes:
current-connectionstls-handshake-failuresconnection-queue-lengthrequest-queue-lengthconnections-per-second
11.4 ASP.NET Core HTTP Connections (SignalR)
Counters:
current-connectionsconnections-startedconnections-stoppedconnections-timed-outconnection-duration
Useful for:
- WebSockets
- SignalR
- Real-time APIs
11.5 System.Net.Http
Source:
https://learn.microsoft.com/dotnet/core/diagnostics/available-counters
Counters:
requests-startedrequests-started-raterequests-failedhttp11-connections-current-totalhttp20-streams-current-totalhttp30-connections-establisheddns-lookups-durationsockets-queued
Great for diagnosing:
- Slow outbound APIs
- Connection pooling issues
11.6 EF Core Metrics (Modern + Legacy)
Source:
https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/metrics
EF Core Built-in Metrics (New API)
microsoft.entityframeworkcore.query.compilation-eventsmicrosoft.entityframeworkcore.commands.executedmicrosoft.entityframeworkcore.active-dbcontexts
Legacy EventCounters compatible with dotnet-counters
- Query execution count
- Query execution rate
- DbContext count
- Optimistic concurrency failures
12. Interpreting dotnet-counters Output
Example snapshot:
Allocation Rate 50,067,464 B/sec
GC Heap Size 239 MB
Working Set 491 MB
ThreadPool Completed/1sec 609
Lock Contention Count/sec 2
Time paused by GC 0
CPU Usage 5%
Code language: JavaScript (javascript)
Interpretation:
- High allocation rate → future GC pressure
- Large heap → memory-heavy workload
- Large working set → big resident memory footprint
- Lock contention → possible bottleneck
- Nonzero Gen2 size → long-lived allocations
- JIT activity → warm-up in progress
- High request rate → check RPS counters in Hosting provider
13. When dotnet-counters is Most Valuable
🟢 Development
- Validate memory patterns
- Analyze LINQ allocations
- Investigate EF Core inefficiencies
🟡 Load Testing
- See RPS
- See GC stress
- See thread starvation
🔵 Staging/UAT
- Compare performance baseline
🔴 Production
- Safe to use
- Zero-impact monitoring
- Perfect for Kubernetes
14. Performance Use Cases (Real World)
✔ Memory Leak Detection
Watch:
- GC Heap Size (keeps growing?)
- Gen 2 Size
- LOH Size
✔ High CPU Investigation
Watch:
- CPU Usage (%)
- Allocation Rate
- JIT time
- Lock contention
✔ GC Bottleneck
Watch:
- % Time in GC
- Time paused by GC
- Gen 0/1/2 Count
- Allocation Rate
✔ ThreadPool Starvation
Watch:
- ThreadPool Queue Length
- ThreadPool Completed Work Items
- Thread Count
✔ ASP.NET Core Throughput
Watch:
- RPS
- Failure rate
- Current requests
- Connection count
✔ EF Core Problem Analysis
Watch:
- Queries/sec
- Active DbContexts
- Command execution count
15. Advantages of dotnet-counters
💠 Cross-platform (Windows, Linux, macOS)
💠 Zero overhead (production-friendly)
💠 Instant insights
💠 No process restart
💠 No profilers needed
💠 No code changes
💠 Works in Docker, Kubernetes, cloud
💠 Works with all .NET apps (5/6/7/8/9+)
💠 Supports both EventCounters and Metrics API
16. Benefits
🎯 Rapid diagnosis
Find issues instantly (CPU, GC, memory, queries).
🎯 Safe for production
Unlike profilers, does not slow down your app.
🎯 Complements logs & APM
Fills the gap between logs, traces, and dumps.
🎯 Helps tune performance
Identify:
- Excessive allocations
- Slow queries
- ThreadPool starvation
- High RPS behavior
🎯 Helps SREs
Useful for:
- Incident analysis
- Postmortems
- Capacity planning
17. Best Practices
- Always include
System.Runtimefirst - Add more providers only as needed
- Use
collectfor long sessions - Compare snapshots at:
- Idle
- Under load
- After runaway memory events
- Capture before & after deployment
- Combine with:
dotnet-tracedotnet-gcdumpdotnet-dump- Application logs
18. Full Example Command Set
Monitor everything:
dotnet-counters monitor -p <PID> \
System.Runtime \
Microsoft.AspNetCore.Hosting \
Microsoft-AspNetCore-Server-Kestrel \
Microsoft.AspNetCore.Http.Connections \
System.Net.Http \
Microsoft.EntityFrameworkCore
Code language: CSS (css)
Collect to file:
dotnet-counters collect -p <PID> -o metrics.json
Code language: HTML, XML (xml)
List processes:
dotnet-counters ps
List counter providers & documentation:
dotnet-counters list
Code language: PHP (php)
19. Putting It All Together (One-Page Summary)
dotnet-counters = Live Performance Insights for .NET Applications
| Category | What You See | Benefit |
|---|---|---|
| Runtime | CPU, GC, memory, threads, locks | Diagnose bottlenecks |
| ASP.NET Core | RPS, requests, failures | Web performance |
| Kestrel | connections, TLS, queues | Server-level insight |
| System.Net | outbound requests, pools | Networking issues |
| EF Core | queries, contexts, failures | DB performance |
| Diagnostics | warm-up, JIT, timers | Startup tuning |
20. Conclusion
dotnet-counters is the single most powerful, lightweight, cross-platform tool for understanding live .NET performance.
It gives developers, performance engineers, and SREs the ability to see:
- How much memory is being allocated
- How often GC is running
- Whether the app is CPU-bound
- Whether threads are starving
- Whether HTTP requests are queuing
- Whether EF Core is overloaded
Without restarts.
Without downtime.
Without profilers.
Without risk.
I’m a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at Cotocus. I share tech blog at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow , and SEO strategies at Wizbrand.
Do you want to learn Quantum Computing?
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at WIZBRAND