Metreja.Tool 0.3.10

dotnet tool install --global Metreja.Tool --version 0.3.10
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Metreja.Tool --version 0.3.10
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Metreja.Tool&version=0.3.10
                    
nuke :add-package Metreja.Tool --version 0.3.10
                    

Metreja

A .NET profiler built for AI coding agents. Tell your agent "find why this is slow" or "where am I wasting memory?" and get an answer backed by real profiling data — no detours, no GUIs, no context switching.

Every operation is a CLI command. Every output is machine-readable. The full measure-analyze-fix loop runs without human intervention.

You: "This endpoint takes 3 seconds, find out why"

Agent: Setting up profiling session...
       Running with profiler attached...
       Analyzing trace (42,381 events captured)...

       Top hotspots (by self time):
       ┌──────────────────────────────────┬───────┬────────────┬───────────┐
       │ Method                           │ Calls │ Self (ms)  │ Incl (ms) │
       ├──────────────────────────────────┼───────┼────────────┼───────────┤
       │ OrderService.ValidateInventory   │    47 │    1,842.3 │   2,104.1 │
       │ DbContext.SaveChangesInternal    │    12 │      891.7 │     891.7 │
       │ PricingEngine.CalculateDiscount  │   312 │      203.4 │     247.8 │
       └──────────────────────────────────┴───────┴────────────┴───────────┘

       ValidateInventory is your bottleneck — 1.8s of self time across
       47 calls. It queries inventory per-item instead of batching.
       Here's the fix...

Why Metreja

  • Profiling without the detour — no separate tool, no manual setup. Your agent profiles as part of fixing the problem.
  • Finds the real bottleneck — self-time analysis pinpoints the method that's actually slow, not the one that calls it.
  • Catches wastefulness — excessive allocations, GC thrashing, memory pressure. See which types allocate the most and which methods trigger gen2 collections.
  • Proves the fix worked — diff two traces. See the numbers. No guessing whether your change helped.
  • Traces only your code — filter by assembly, namespace, or class. Framework noise stays out, overhead stays low.
  • Reproducible — session configs are isolated files. Re-run the same investigation anytime.

Installation

Prerequisites: .NET 8 SDK or later, Windows 10/11 (x64)

dotnet tool install -g Metreja.Tool

After installation, the metreja command is available globally.

Claude Code Plugin

Install the metreja-profiler plugin and Claude handles everything automatically — session setup, profiling, analysis, and fix suggestions. Just ask a question.

/plugin marketplace add kodroi/metreja-profiler-marketplace
/plugin install metreja-profiler@metreja-profiler-marketplace

Quick Start

Five commands from zero to actionable hotspot data:

# 1. Create a session
SESSION=$(metreja init --scenario "baseline")

# 2. Tell it what to trace (your code, not the framework)
metreja add include -s $SESSION --assembly MyApp
metreja add exclude -s $SESSION --assembly "System.*"
metreja add exclude -s $SESSION --assembly "Microsoft.*"

# 3. Generate the profiler environment and run your app
metreja generate-env -s $SESSION --format shell > env.sh
source env.sh && dotnet run --project src/MyApp -c Release

# 4. Find the bottleneck
metreja hotspots .metreja/output/*.ndjson --top 10

# 5. Drill into the slowest method
metreja calltree .metreja/output/*.ndjson --method "ValidateInventory"

What You Can Measure

Performance hotspots — Find the slowest methods ranked by self time, inclusive time, call count, or allocation count.

metreja hotspots trace.ndjson --top 10 --sort self
metreja hotspots trace.ndjson --filter "MyApp.Services" --min-ms 1

Call trees — See exactly what a slow method does internally, with timing at every level.

metreja calltree trace.ndjson --method "ProcessOrder"
metreja calltree trace.ndjson --method "ProcessOrder" --occurrence 2  # 2nd slowest call

Caller analysis — Find out who calls a method and how much time each caller contributes.

metreja callers trace.ndjson --method "SaveChanges" --top 10

Memory and GC pressure — GC counts by generation, pause times, and per-type allocation hotspots.

metreja memory trace.ndjson --top 20
metreja memory trace.ndjson --filter "System.String"

Before/after comparison — Diff two traces to verify a fix actually improved performance.

metreja analyze-diff baseline.ndjson optimized.ndjson

CLI Reference

Session Management

init

Create a new profiling session. Returns a random 6-hex-char session ID.

Option Type Default Description
--scenario string Optional scenario name
metreja init
metreja init --scenario "before-refactor"
add include / add exclude

Add filter rules controlling which methods get traced. Supports wildcards (*).

Option Type Default Description
-s, --session string Required. Session ID
--assembly string[] * Assembly name pattern
--namespace string[] * Namespace pattern
--class string[] * Class name pattern
--method string[] * Method name pattern
metreja add include -s a1b2c3 --assembly MyApp
metreja add include -s a1b2c3 --namespace "MyApp.Core"
metreja add include -s a1b2c3 --namespace "MyApp.Services"
metreja add exclude -s a1b2c3 --class "*Generated*"

Note: Only one level option (--assembly, --namespace, --class, or --method) can be used per add/remove command. To filter multiple levels, use separate commands. Multiple patterns per level are supported in add (e.g., --namespace "A" --namespace "B").

How Filters Work

A method is traced if it matches any include rule AND does not match any exclude rule.

  • Include-first, then exclude: If includes are defined, only methods matching at least one include rule are candidates. Excludes then remove specific methods from that set.
  • One level per command: Each add include/add exclude command accepts a single level (--assembly, --namespace, --class, or --method) but can take multiple patterns at that level.
  • Zero ELT3 overhead for excluded methods: Filters are evaluated at JIT time via FunctionIDMapper2. Excluded methods never get ELT3 hooks installed — there is no per-call cost.

Example — trace an assembly but exclude generated code:

metreja add include -s a1b2c3 --assembly MyApp
metreja add exclude -s a1b2c3 --namespace "MyApp.Generated"
metreja add exclude -s a1b2c3 --class "*ApiClient"
remove include / remove exclude

Remove a filter rule by exact match.

Option Type Default Description
-s, --session string Required. Session ID
--assembly string * Assembly name pattern
--namespace string * Namespace pattern
--class string * Class name pattern
--method string * Method name pattern
metreja remove include -s a1b2c3 --namespace "MyApp.Core"
clear-filters

Clear all filter rules from a session.

Option Type Default Description
-s, --session string Required. Session ID
--type string include, exclude, or omit for both
metreja clear-filters -s a1b2c3
metreja clear-filters -s a1b2c3 --type include
set

Configure session settings via subcommands.

Subcommand Arguments Description
set metadata -s ID "scenario-name" Update scenario name
set output -s ID "path/pattern.ndjson" Set output path (supports {sessionId}, {pid} tokens)
set max-events -s ID 50000 Cap event count (0 = unlimited)
set compute-deltas -s ID true Enable delta timing for performance analysis
set events -s ID enter leave method_stats Set enabled event types
set stats-flush-interval -s ID 30 Periodic stats flush interval in seconds (0 = disabled, default 30)

Tip: All subcommands support --help for detailed usage (e.g., metreja set events --help).

validate

Check session configuration for errors. Exits with code 1 on failure.

metreja validate -s a1b2c3
generate-env

Generate a script that sets the environment variables to attach the profiler.

Option Type Default Description
-s, --session string Required. Session ID
--format string batch batch, powershell, or shell
--force bool false Generate even if profiler DLL is not found
metreja generate-env -s a1b2c3
metreja generate-env -s a1b2c3 --format powershell
metreja generate-env -s a1b2c3 --format shell
clear

Delete profiling sessions.

metreja clear -s a1b2c3
metreja clear --all

Analysis Commands

hotspots

Per-method timing ranked by self time, inclusive time, call count, or allocations.

Option Type Default Description
file string Required. NDJSON trace file
--top int 20 Number of methods to show
--min-ms double 0.0 Minimum time threshold (ms)
--sort string self self, inclusive, calls, or allocs
--filter string[] Filter by method/class/namespace pattern
calltree

Call tree for a specific method invocation, slowest first.

Option Type Default Description
file string Required. NDJSON trace file
--method string Required. Method name or pattern
--tid long Filter by thread ID
--occurrence int 1 Which invocation (1 = slowest)
callers

Who calls a method, with call count and timing per caller.

Option Type Default Description
file string Required. NDJSON trace file
--method string Required. Method name or pattern
--top int 20 Number of callers to show
memory

GC summary (generation counts, pause times) and per-type allocation hotspots.

Option Type Default Description
file string Required. NDJSON trace file
--top int 20 Number of allocation types
--filter string[] Filter by class name pattern
analyze-diff

Compare two traces. Shows per-method timing delta (base vs. compare).

Argument Type Description
base string Required. Base NDJSON file
compare string Required. Comparison NDJSON file
report

Report an issue to the GitHub repository. Requires the GitHub CLI (gh) installed and authenticated.

Option Type Default Description
-t, --title string Required. Issue title
-d, --description string Required. Issue body/description
metreja report --title "Bug: crash on empty trace" --description "Detailed description of the issue."

Exit codes:

  • 0 — Issue created successfully
  • 1 — Issue creation failed (prints GitHub error)
  • 2 — GitHub CLI not installed
  • 3 — GitHub CLI not authenticated

Session Config Format

Stored at .metreja/sessions/{sessionId}.json:

{
  "sessionId": "a1b2c3",
  "metadata": { "scenario": "baseline" },
  "instrumentation": {
    "maxEvents": 0,
    "computeDeltas": true,
    "statsFlushIntervalSeconds": 30,
    "includes": [
      { "assembly": "MyApp", "namespace": "*", "class": "*", "method": "*" }
    ],
    "excludes": []
  },
  "output": {
    "path": ".metreja/output/{sessionId}_{pid}.ndjson"
  }
}
Field Type Default Description
maxEvents int 0 Event cap per session (0 = unlimited)
computeDeltas bool true Include delta timing on leave events
statsFlushIntervalSeconds int 30 Periodic stats flush interval (0 = disabled). Protects against data loss when the profiled process is force-killed.

Output Path Tokens

Token Replaced With
{sessionId} Session ID from config
{pid} Process ID of the profiled app
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.3.10 0 3/13/2026
0.3.9 0 3/13/2026
0.3.8 0 3/13/2026
0.3.7 15 3/13/2026
0.3.6 82 3/9/2026
0.3.5 77 3/8/2026
0.3.4 77 3/8/2026
0.3.3 82 3/6/2026
0.3.2 80 3/3/2026
0.3.1 86 3/2/2026
0.3.0 78 3/2/2026
0.2.5 87 3/1/2026
0.2.4 81 3/1/2026
0.2.3 77 3/1/2026
0.2.2 81 3/1/2026
0.2.1 85 2/28/2026
0.2.0 82 2/28/2026
0.1.2 85 2/28/2026
0.1.1 85 2/28/2026
0.1.0 79 2/28/2026