How to Collect and Analyze .NET Performance Traces Using dotnet-trace
Use dotnet-trace to capture CPU, GC, and allocation events from running .NET processes via command-line collection, then analyze results using dotnet-trace report or speedscope-compatible exports.
The dotnet-trace tool provides a cross-platform solution for gathering managed-code performance data without modifying application source code. According to the dotnet/skills repository, the dotnet-trace-collect skill implements standardized workflows for installing the tool, discovering target processes, and exporting traces in formats compatible with modern analysis tools.
Installing dotnet-trace
The tool supports two installation methods depending on your environment constraints.
Via .NET SDK (Recommended):
dotnet tool install -g dotnet-trace
Standalone Binary (No SDK Required):
When the .NET SDK is unavailable, download the pre-built binary directly from the official aka.ms redirect. In plugins/dotnet-diag/skills/dotnet-trace-collect/references/dotnet-trace-collect.md, the skill specifies this fallback for containerized environments:
curl -JL https://aka.ms/dotnet-trace/linux-x64 -o dotnet-trace
chmod +x dotnet-trace
Discovering Target Processes
Before collecting traces, identify running .NET processes using the built-in process list command:
dotnet-trace ps
This outputs process IDs (PIDs) and corresponding command lines, which you pass to the collection commands via the -p parameter.
Collecting Performance Traces
The dotnet-trace collect command supports multiple configuration strategies for different diagnostic scenarios.
Using Predefined Profiles
Profiles bundle common EventSource providers into convenient presets. According to the reference documentation in dotnet-trace-collect.md, available profiles include:
- dotnet-sampled-thread-time: CPU sampling for thread time analysis
- gc-verbose: Garbage collection start/stop events with detailed allocation data
dotnet-trace collect -p <PID> --profile gc-verbose -o /tmp/gc.nettrace
Custom Provider Configuration
For targeted diagnostics, specify individual providers as comma-separated values:
dotnet-trace collect -p <PID> \
--providers System.Net.Http,System.Net.NameResolution,System.Net.Security,System.Net.Sockets \
-o /tmp/network.nettrace
Common provider names include Microsoft-Windows-DotNETRuntime for runtime events and System.Net.Http for network I/O tracking.
Time-Limited Collection
Prevent unbounded trace files by setting explicit durations using the --duration flag:
dotnet-trace collect -p <PID> --duration 00:00:30 -o /tmp/short.nettrace
This stops collection automatically after 30 seconds.
Exporting to speedscope Format
For web-based flame graph visualization, export directly to JSON format compatible with speedscope:
dotnet-trace collect -p <PID> --format speedscope -o /tmp/trace.json
This bypasses the default .nettrace binary format and generates immediately viewable output.
Advanced Linux-Only Tracing with collect-linux
For .NET 10+ on Linux, the dotnet-trace collect-linux variant provides kernel-level event capture unavailable to standard collection. As documented in plugins/dotnet-diag/skills/dotnet-trace-collect/references/dotnet-trace-collect-linux.md, this mode utilizes the perf_events subsystem to capture native stacks and kernel events.
Requirements:
- Root privileges (required for
perf_eventsaccess) - .NET 10 or later runtime
- Linux host environment
sudo dotnet-trace collect-linux -p <PID> --profile thread-time -o /tmp/linux.nettrace
This approach captures native frames from P/Invoke calls and interop layers that standard managed-code collection misses.
Analyzing Trace Output
After collection, analyze .nettrace files using the built-in reporting tool:
dotnet-trace report /tmp/trace.nettrace
This displays summary statistics including event counts, CPU usage distributions, and GC pause durations. For graphical analysis, open .nettrace files in PerfView or Visual Studio, or upload speedscope JSON exports to compatible web viewers.
Summary
- Installation: Use
dotnet tool install -g dotnet-tracewhen SDK is available; otherwise download platform-specific binaries fromaka.msredirects. - Process Discovery: Run
dotnet-trace psto identify target PIDs before collection. - Collection Modes: Standard
collectworks across all platforms for managed code;collect-linuxrequires root but captures native stacks viaperf_eventson Linux with .NET 10+. - Output Formats: Default
.nettracefiles work with PerfView and Visual Studio; use--format speedscopefor web-based flame graphs. - Reference Sources: Implementation details reside in
plugins/dotnet-diag/skills/dotnet-trace-collect/references/dotnet-trace-collect.mdanddotnet-trace-collect-linux.md, with evaluation logic intests/dotnet-diag/dotnet-trace-collect/eval.yaml.
Frequently Asked Questions
How do I collect traces from a .NET application running in a container without the SDK installed?
Download the standalone dotnet-trace binary using the aka.ms redirect URL for your container's architecture. As specified in the dotnet-trace-collect skill reference, you can curl the binary directly, make it executable, and run collection commands without installing the full .NET SDK.
What is the difference between dotnet-trace collect and dotnet-trace collect-linux?
The standard collect command captures managed-code events using EventSource providers and works across Windows, macOS, and Linux. The collect-linux variant, available only for .NET 10+ on Linux, leverages the kernel's perf_events subsystem to capture native stack frames and kernel events, but requires root privileges to access these low-level metrics.
Can I limit how long a trace runs to prevent generating huge files?
Yes. Use the --duration parameter with a timespan format (HH:MM:SS) to automatically stop collection after the specified interval. For example, --duration 00:01:00 captures exactly 60 seconds of data before terminating the session.
How do I analyze network performance specifically using dotnet-trace?
Specify the network-related EventSource providers using the --providers flag. Include System.Net.Http,System.Net.NameResolution,System.Net.Security,System.Net.Sockets to capture DNS resolution, TLS handshake, and socket I/O events. Collect the trace and then use dotnet-trace report to analyze latency and throughput patterns.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →