Claude Skill

dotnet-asynkron-profiler

Use the open-source free `Asynkron.Profiler` dotnet tool for CLI-first CPU, allocation, exception, contention, and heap profiling of .NET commands or existing trace artifacts.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download postpartum-genushyacinthus29-dotnet-skills-skills_dotnet-asynkron-profiler-bfa4ebd.zip · 6 KB
Part of postpartum-genushyacinthus29/dotnet-skills — 80 skills

Install

skills CLI npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills/tree/main/skills/dotnet-asynkron-profiler
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install postpartum-genushyacinthus29-dotnet-skills@llmmart
Git git clone https://github.com/Postpartum-genushyacinthus29/dotnet-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole postpartum-genushyacinthus29/dotnet-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Asynkron.Profiler

Trigger On

  • the repo wants Asynkron.Profiler or asynkron-profiler
  • the user wants automation-friendly profiling output instead of GUI-only tooling
  • profiling needs are CPU, allocation, exception, contention, or heap focused and should land as plain-text summaries in CI, scripts, or agent workflows
  • the task needs to render an existing .nettrace, .speedscope.json, .etlx, or .gcdump file into a readable report

Workflow

  1. Decide whether the task is a new profile capture or rendering an existing trace artifact.
  2. Prefer built Release output over dotnet run so the trace represents the target app rather than restore/build noise.
  3. Install and verify all three tools before assuming the profiler is usable:
    • asynkron-profiler
    • dotnet-trace
    • dotnet-gcdump
  4. Choose exactly one primary mode first:
    • --cpu
    • --memory
    • --exception
    • --contention
    • --heap
  5. Use --input <path> when the trace already exists and the task is about rendering or narrowing the report, not recollecting data.
  6. Refine the output only after the baseline run:
    • --root <text> to anchor the call tree
    • --filter <text> to trim tables
    • --exception-type <text> for exception-heavy flows
    • --calltree-depth, --calltree-width, --calltree-self, --calltree-sibling-cutoff
  7. Treat profile-output/ as the stable output folder for review artifacts and reruns.
  8. If the task needs process attach, counters, or raw official diagnostics flows rather than this CLI frontend, hand off to dotnet-profiling.

Architecture

flowchart LR
  A["Profiling task"] --> B{"New run or existing artifact?"}
  B -->|New run| C["Build target in Release"]
  C --> D["Run `asynkron-profiler --mode -- <command|csproj|sln>`"]
  D --> E["Collect via `dotnet-trace` or `dotnet-gcdump`"]
  E --> F["Write reports to `profile-output/`"]
  B -->|Existing artifact| G["Run `asynkron-profiler --input <path> [--mode]`"]
  G --> F
  F --> H["Refine output with `--root`, `--filter`, and call tree flags"]

Install

  • Install the profiler tool from upstream:
dotnet tool install -g asynkron-profiler --prerelease
  • Install prerequisites:
dotnet tool install -g dotnet-trace
dotnet tool install -g dotnet-gcdump
  • Verify the toolchain:
asynkron-profiler --help
dotnet-trace --version
dotnet-gcdump --version

Practical Usage

Capture a new profile

dotnet build -c Release
asynkron-profiler --cpu -- ./bin/Release/<tfm>/MyApp

Framework-dependent apps can run through dotnet:

asynkron-profiler --memory -- dotnet ./bin/Release/<tfm>/MyApp.dll

Project and solution paths are also valid when the tool should build and run for you:

asynkron-profiler --contention -- ./MyApp.csproj
asynkron-profiler --exception -- ./MySolution.sln

Render an existing trace

asynkron-profiler --input ./profile-output/app.nettrace --cpu
asynkron-profiler --input ./profile-output/app.etlx --memory
asynkron-profiler --input ./profile-output/app.gcdump --heap

Manual collection with the official tools still fits when the trace must be captured separately:

dotnet-trace collect --output ./profile-output/app.nettrace -- dotnet run MyProject.sln
asynkron-profiler --input ./profile-output/app.nettrace --cpu

Option Patterns

  • mode flags:
    • --cpu for sampled hotspots
    • --memory for GC allocation ticks and per-type call trees
    • --exception for thrown counts and throw-site trees
    • --contention for wait-time trees
    • --heap for retained heap shape via dotnet-gcdump
  • scope and readability:
    • --root <text> to focus the tree on a subsystem
    • --filter <text> to narrow function tables
    • --exception-type <text> when one exception dominates the signal
  • output shaping:
    • --calltree-depth <n>
    • --calltree-width <n>
    • --calltree-self
    • --calltree-sibling-cutoff <n>
  • trace replay and project targeting:
    • --input <path> for .nettrace, .speedscope.json, .etlx, or .gcdump
    • --tfm <tfm> when the profiler must resolve a specific target framework from a .csproj or .sln

Constraints

  • upstream currently documents .NET SDK 10.x as the supported toolchain baseline
  • dotnet run is supported but usually produces noisy traces because it captures host, restore, and build work
  • the tool is a frontend over dotnet-trace and dotnet-gcdump, so missing prerequisites or blocked diagnostics IPC will break runs
  • --heap captures retained heap shape, not CPU or allocation timelines
  • this skill is for launched commands or existing trace files; if the task is process attach, counters, or raw trace authoring, prefer dotnet-profiling

Deliver

  • a repeatable asynkron-profiler command path for the profiling mode that matches the problem
  • explicit install and prerequisite commands
  • a clear baseline command plus any focused --root, --filter, --exception-type, or call-tree options needed for readable output
  • trace replay guidance when the task starts from an existing artifact

Validate

  • asynkron-profiler --help, dotnet-trace --version, and dotnet-gcdump --version all succeed
  • the chosen profiling mode matches the question being investigated
  • the command profiles built Release output unless there is a documented reason to accept dotnet run noise
  • profile-output/ contains the expected report or artifact after the run
  • any replay flow uses an input file type that matches the selected mode

References

  • overview.md - tool positioning, install paths, prerequisites, and when to choose it over raw diagnostics CLIs
  • commands.md - command patterns for capture, replay, and option tuning
  • examples.md - mode-by-mode examples, output expectations, and troubleshooting checks
Files (dotnet-skills)
  • references
    • commands.md 3 KB
      # Asynkron.Profiler Commands
      
      ## Baseline Verification
      
      ```bash
      asynkron-profiler --help
      dotnet-trace --version
      dotnet-gcdump --version
      ```
      
      ## Capture New Profiles
      
      Build first:
      
      ```bash
      dotnet build -c Release
      ```
      
      CPU profile the compiled app:
      
      ```bash
      asynkron-profiler --cpu -- ./bin/Release/<tfm>/MyApp
      ```
      
      Profile a framework-dependent app:
      
      ```bash
      asynkron-profiler --cpu -- dotnet ./bin/Release/<tfm>/MyApp.dll
      ```
      
      Profile a project or solution directly:
      
      ```bash
      asynkron-profiler --cpu -- ./MyApp.csproj
      asynkron-profiler --cpu -- ./MySolution.sln
      ```
      
      Only use `dotnet run` when you accept build and host noise:
      
      ```bash
      asynkron-profiler --cpu -- dotnet run -c Release ./MyApp.csproj
      ```
      
      ## Mode Commands
      
      CPU hotspots:
      
      ```bash
      asynkron-profiler --cpu -- ./bin/Release/<tfm>/MyApp
      ```
      
      Allocation profiling:
      
      ```bash
      asynkron-profiler --memory -- ./bin/Release/<tfm>/MyApp
      ```
      
      Thrown exceptions:
      
      ```bash
      asynkron-profiler --exception -- ./bin/Release/<tfm>/MyApp
      ```
      
      Lock contention:
      
      ```bash
      asynkron-profiler --contention -- ./bin/Release/<tfm>/MyApp
      ```
      
      Heap snapshot:
      
      ```bash
      asynkron-profiler --heap -- ./bin/Release/<tfm>/MyApp
      ```
      
      ## Replay Existing Artifacts
      
      Auto-select from file extension:
      
      ```bash
      asynkron-profiler --input /path/to/trace.nettrace
      ```
      
      Force CPU rendering for a Speedscope file:
      
      ```bash
      asynkron-profiler --input /path/to/trace.speedscope.json --cpu
      ```
      
      Render memory from `.etlx`:
      
      ```bash
      asynkron-profiler --input /path/to/trace.etlx --memory
      ```
      
      Render contention from `.etlx`:
      
      ```bash
      asynkron-profiler --input /path/to/trace.etlx --contention
      ```
      
      Render exceptions from `.etlx`:
      
      ```bash
      asynkron-profiler --input /path/to/trace.etlx --exception
      ```
      
      Render a heap dump:
      
      ```bash
      asynkron-profiler --input /path/to/heap.gcdump --heap
      ```
      
      ## Tuning Output
      
      Anchor the tree to one subsystem:
      
      ```bash
      asynkron-profiler --memory --root "MyNamespace" -- ./bin/Release/<tfm>/MyApp
      ```
      
      Reduce call tree noise:
      
      ```bash
      asynkron-profiler --cpu --calltree-depth 8 --calltree-width 6 -- ./bin/Release/<tfm>/MyApp
      ```
      
      Inspect self time:
      
      ```bash
      asynkron-profiler --cpu --calltree-self -- ./bin/Release/<tfm>/MyApp
      ```
      
      Focus exception analysis:
      
      ```bash
      asynkron-profiler --exception --exception-type "InvalidOperationException" -- ./bin/Release/<tfm>/MyApp
      ```
      
      Filter function tables:
      
      ```bash
      asynkron-profiler --contention --filter "MyApp.Services" -- ./bin/Release/<tfm>/MyApp
      ```
      
      Target a specific framework from a project:
      
      ```bash
      asynkron-profiler --cpu --tfm net10.0 -- ./MyApp.csproj
      ```
      
      ## Manual Official-Tool Collection Plus Replay
      
      Collect first with `dotnet-trace`, then render:
      
      ```bash
      dotnet-trace collect --output ./profile-output/app.nettrace -- dotnet run MyProject.sln
      asynkron-profiler --input ./profile-output/app.nettrace --cpu
      ```
      
      This pattern is useful when:
      
      - the trace is collected in CI or another machine
      - you want to archive raw traces separately from the rendered report
      - a later task needs multiple render passes over the same artifact
      
    • examples.md 2.7 KB
      # Asynkron.Profiler Examples
      
      ## CPU
      
      Use `--cpu` for sampled hotspots and top-function tables.
      
      ```bash
      dotnet build -c Release examples/cpu/CpuDemo.csproj
      asynkron-profiler --cpu -- ./examples/cpu/bin/Release/net10.0/CpuDemo
      ```
      
      What to expect:
      
      - a total-time call tree
      - top functions by sampled time
      - optional self-time view when `--calltree-self` is enabled
      
      ## Memory
      
      Use `--memory` for allocation-heavy paths and per-type call trees.
      
      ```bash
      dotnet build -c Release examples/memory/MemoryDemo.csproj
      asynkron-profiler --memory -- ./examples/memory/bin/Release/net10.0/MemoryDemo
      ```
      
      What to expect:
      
      - allocation totals by type
      - a sampled allocation call tree
      - better signal when the workload is large enough to emit GC allocation ticks
      
      ## Exceptions
      
      Use `--exception` when thrown exceptions are part of the performance or correctness issue.
      
      ```bash
      dotnet build -c Release examples/exception/ExceptionDemo.csproj
      asynkron-profiler --exception --exception-type "InvalidOperation" -- ./examples/exception/bin/Release/net10.0/ExceptionDemo
      ```
      
      What to expect:
      
      - thrown counts
      - throw-site call tree
      - narrower output when `--exception-type` is supplied
      
      ## Contention
      
      Use `--contention` for lock-heavy or thread-blocking scenarios.
      
      ```bash
      dotnet build -c Release examples/contention/ContentionDemo.csproj
      asynkron-profiler --contention -- ./examples/contention/bin/Release/net10.0/ContentionDemo
      ```
      
      What to expect:
      
      - wait-time call tree
      - top contended methods
      - clearer results when the workload creates repeatable contention
      
      ## Heap
      
      Use `--heap` when retained-memory shape matters more than allocation rate.
      
      ```bash
      dotnet build -c Release examples/heap/HeapDemo.csproj
      asynkron-profiler --heap -- ./examples/heap/bin/Release/net8.0/HeapDemo
      ```
      
      What to expect:
      
      - top retained types
      - heap byte totals and object counts
      - a snapshot view rather than an allocation timeline
      
      ## Troubleshooting
      
      ### Missing prerequisites
      
      If the command fails because a prerequisite tool is missing:
      
      ```bash
      dotnet tool install -g asynkron-profiler --prerelease
      dotnet tool install -g dotnet-trace
      dotnet tool install -g dotnet-gcdump
      ```
      
      ### Diagnostics IPC failures
      
      If you see diagnostics session or IPC creation failures:
      
      - confirm the target process allows diagnostics
      - avoid `DOTNET_EnableDiagnostics=0`
      - avoid `COMPlus_EnableDiagnostics=0`
      - run the profiler as the same user that launches the target process
      
      ### Empty or weak data
      
      If the output is empty or not useful:
      
      - rerun against built `Release` output instead of `dotnet run`
      - increase the workload or iteration count
      - use the mode that matches the signal:
        - CPU for hotspots
        - memory for allocations
        - contention for lock waits
        - heap for retained memory
      - verify the input artifact matches the replay mode
      
    • overview.md 3.3 KB
      # Asynkron.Profiler Overview
      
      ## Official Sources
      
      - GitHub repository:
        - <https://github.com/asynkron/Asynkron.Profiler>
      - Upstream README:
        - <https://github.com/asynkron/Asynkron.Profiler/blob/main/README.md>
      - Tool project:
        - <https://github.com/asynkron/Asynkron.Profiler/blob/main/src/ProfileTool/ProfileTool.csproj>
      - Releases:
        - <https://github.com/asynkron/Asynkron.Profiler/releases>
      
      ## What The Tool Is
      
      `Asynkron.Profiler` is a dotnet global tool that wraps `dotnet-trace` and `dotnet-gcdump` with a CLI focused on readable profiling output for humans, scripts, and agents.
      
      Its core value is not raw trace collection alone. It gives you:
      
      - a single command surface for CPU, memory, exception, contention, and heap scenarios
      - plain-text summaries suitable for terminals, CI logs, or agent workflows
      - replay support for existing `.nettrace`, `.speedscope.json`, `.etlx`, and `.gcdump` artifacts
      
      ## Install Paths
      
      Install the profiler itself:
      
      ```bash
      dotnet tool install -g asynkron-profiler --prerelease
      ```
      
      Install required prerequisites:
      
      ```bash
      dotnet tool install -g dotnet-trace
      dotnet tool install -g dotnet-gcdump
      ```
      
      Verify:
      
      ```bash
      asynkron-profiler --help
      dotnet-trace --version
      dotnet-gcdump --version
      ```
      
      Upstream currently documents `.NET SDK 10.x` as the expected baseline.
      
      ## When To Use This Skill
      
      Use `dotnet-asynkron-profiler` when:
      
      - the repo wants readable profiling output without opening a GUI profiler
      - you need one command that can both collect and render performance data
      - CI or agent automation should keep profiling artifacts and summaries in a stable folder
      - you already have a trace file and want a focused report from it
      
      Use `dotnet-profiling` instead when:
      
      - you need the official .NET diagnostics CLIs directly
      - you need attach-by-PID, counters, or lower-level trace authoring
      - the repo intentionally does not want an extra profiler frontend
      
      ## Input And Output Model
      
      ### New capture flow
      
      1. Build or choose the target command.
      2. Run `asynkron-profiler` in one mode.
      3. The tool invokes `dotnet-trace` or `dotnet-gcdump` as needed.
      4. Results are written to `profile-output/`.
      
      ### Replay flow
      
      1. Point `--input` at an existing artifact.
      2. Optionally force the mode.
      3. Render the structured report without rerunning the application.
      
      ## Supported Input Types
      
      - CPU:
        - `.speedscope.json`
        - `.nettrace`
      - Memory:
        - `.nettrace`
        - `.etlx`
      - Exceptions:
        - `.nettrace`
        - `.etlx`
      - Contention:
        - `.nettrace`
        - `.etlx`
      - Heap:
        - `.gcdump`
        - `dotnet-gcdump report` text output
      
      ## Practical Defaults
      
      - prefer built `Release` output over `dotnet run`
      - start with one mode and only add filters after the baseline run
      - keep `profile-output/` under the working directory so traces and reports stay together
      - use project or solution paths only when you intentionally want the tool to build and run on your behalf
      
      ## Constraints And Tradeoffs
      
      - if `dotnet-trace` or `dotnet-gcdump` is missing from `PATH`, the profiler cannot collect data
      - disabled diagnostics IPC on the target process will break trace collection
      - `--heap` gives retained-memory shape, not live allocation timelines
      - `dotnet run` is convenient but usually less accurate than pointing at the compiled output
      - replay mode is ideal for narrowing or sharing a trace, but it cannot recover events that were never captured in the original artifact
      
  • SKILL.md 6.2 KB
    ---
    name: dotnet-asynkron-profiler
    version: "1.0.0"
    category: "Metrics"
    description: "Use the open-source free `Asynkron.Profiler` dotnet tool for CLI-first CPU, allocation, exception, contention, and heap profiling of .NET commands or existing trace artifacts."
    compatibility: "Requires the `asynkron-profiler` dotnet tool plus `dotnet-trace` and `dotnet-gcdump`; upstream guidance currently targets .NET SDK 10.x."
    ---
    
    # Asynkron.Profiler
    
    ## Trigger On
    
    - the repo wants `Asynkron.Profiler` or `asynkron-profiler`
    - the user wants automation-friendly profiling output instead of GUI-only tooling
    - profiling needs are CPU, allocation, exception, contention, or heap focused and should land as plain-text summaries in CI, scripts, or agent workflows
    - the task needs to render an existing `.nettrace`, `.speedscope.json`, `.etlx`, or `.gcdump` file into a readable report
    
    ## Workflow
    
    1. Decide whether the task is a new profile capture or rendering an existing trace artifact.
    2. Prefer built `Release` output over `dotnet run` so the trace represents the target app rather than restore/build noise.
    3. Install and verify all three tools before assuming the profiler is usable:
       - `asynkron-profiler`
       - `dotnet-trace`
       - `dotnet-gcdump`
    4. Choose exactly one primary mode first:
       - `--cpu`
       - `--memory`
       - `--exception`
       - `--contention`
       - `--heap`
    5. Use `--input <path>` when the trace already exists and the task is about rendering or narrowing the report, not recollecting data.
    6. Refine the output only after the baseline run:
       - `--root <text>` to anchor the call tree
       - `--filter <text>` to trim tables
       - `--exception-type <text>` for exception-heavy flows
       - `--calltree-depth`, `--calltree-width`, `--calltree-self`, `--calltree-sibling-cutoff`
    7. Treat `profile-output/` as the stable output folder for review artifacts and reruns.
    8. If the task needs process attach, counters, or raw official diagnostics flows rather than this CLI frontend, hand off to `dotnet-profiling`.
    
    ## Architecture
    
    ```mermaid
    flowchart LR
      A["Profiling task"] --> B{"New run or existing artifact?"}
      B -->|New run| C["Build target in Release"]
      C --> D["Run `asynkron-profiler --mode -- <command|csproj|sln>`"]
      D --> E["Collect via `dotnet-trace` or `dotnet-gcdump`"]
      E --> F["Write reports to `profile-output/`"]
      B -->|Existing artifact| G["Run `asynkron-profiler --input <path> [--mode]`"]
      G --> F
      F --> H["Refine output with `--root`, `--filter`, and call tree flags"]
    ```
    
    ## Install
    
    - Install the profiler tool from upstream:
    
    ```bash
    dotnet tool install -g asynkron-profiler --prerelease
    ```
    
    - Install prerequisites:
    
    ```bash
    dotnet tool install -g dotnet-trace
    dotnet tool install -g dotnet-gcdump
    ```
    
    - Verify the toolchain:
    
    ```bash
    asynkron-profiler --help
    dotnet-trace --version
    dotnet-gcdump --version
    ```
    
    ## Practical Usage
    
    ### Capture a new profile
    
    ```bash
    dotnet build -c Release
    asynkron-profiler --cpu -- ./bin/Release/<tfm>/MyApp
    ```
    
    Framework-dependent apps can run through `dotnet`:
    
    ```bash
    asynkron-profiler --memory -- dotnet ./bin/Release/<tfm>/MyApp.dll
    ```
    
    Project and solution paths are also valid when the tool should build and run for you:
    
    ```bash
    asynkron-profiler --contention -- ./MyApp.csproj
    asynkron-profiler --exception -- ./MySolution.sln
    ```
    
    ### Render an existing trace
    
    ```bash
    asynkron-profiler --input ./profile-output/app.nettrace --cpu
    asynkron-profiler --input ./profile-output/app.etlx --memory
    asynkron-profiler --input ./profile-output/app.gcdump --heap
    ```
    
    Manual collection with the official tools still fits when the trace must be captured separately:
    
    ```bash
    dotnet-trace collect --output ./profile-output/app.nettrace -- dotnet run MyProject.sln
    asynkron-profiler --input ./profile-output/app.nettrace --cpu
    ```
    
    ## Option Patterns
    
    - mode flags:
      - `--cpu` for sampled hotspots
      - `--memory` for GC allocation ticks and per-type call trees
      - `--exception` for thrown counts and throw-site trees
      - `--contention` for wait-time trees
      - `--heap` for retained heap shape via `dotnet-gcdump`
    - scope and readability:
      - `--root <text>` to focus the tree on a subsystem
      - `--filter <text>` to narrow function tables
      - `--exception-type <text>` when one exception dominates the signal
    - output shaping:
      - `--calltree-depth <n>`
      - `--calltree-width <n>`
      - `--calltree-self`
      - `--calltree-sibling-cutoff <n>`
    - trace replay and project targeting:
      - `--input <path>` for `.nettrace`, `.speedscope.json`, `.etlx`, or `.gcdump`
      - `--tfm <tfm>` when the profiler must resolve a specific target framework from a `.csproj` or `.sln`
    
    ## Constraints
    
    - upstream currently documents `.NET SDK 10.x` as the supported toolchain baseline
    - `dotnet run` is supported but usually produces noisy traces because it captures host, restore, and build work
    - the tool is a frontend over `dotnet-trace` and `dotnet-gcdump`, so missing prerequisites or blocked diagnostics IPC will break runs
    - `--heap` captures retained heap shape, not CPU or allocation timelines
    - this skill is for launched commands or existing trace files; if the task is process attach, counters, or raw trace authoring, prefer `dotnet-profiling`
    
    ## Deliver
    
    - a repeatable `asynkron-profiler` command path for the profiling mode that matches the problem
    - explicit install and prerequisite commands
    - a clear baseline command plus any focused `--root`, `--filter`, `--exception-type`, or call-tree options needed for readable output
    - trace replay guidance when the task starts from an existing artifact
    
    ## Validate
    
    - `asynkron-profiler --help`, `dotnet-trace --version`, and `dotnet-gcdump --version` all succeed
    - the chosen profiling mode matches the question being investigated
    - the command profiles built `Release` output unless there is a documented reason to accept `dotnet run` noise
    - `profile-output/` contains the expected report or artifact after the run
    - any replay flow uses an input file type that matches the selected mode
    
    ## References
    
    - [overview.md](references/overview.md) - tool positioning, install paths, prerequisites, and when to choose it over raw diagnostics CLIs
    - [commands.md](references/commands.md) - command patterns for capture, replay, and option tuning
    - [examples.md](references/examples.md) - mode-by-mode examples, output expectations, and troubleshooting checks
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related