External performance profiling harness for Claude Code TUI.
Measures UI responsiveness and correlates latency with system resource usage — without modifying Claude Code itself.
# Global install
npm install -g cc-profiler
# Or use npx (no install required)
npx cc-profiler claudeRequirements: Node.js 22+
# Profile a Claude Code session
cc-profiler claude
# When done, quit Claude normally (Ctrl+C or /exit)
# Output:
# cc-profiler session complete
# - Output: ./cc-profiler-session-2026-02-04-135044
# - Data: ./cc-profiler-session-2026-02-04-135044/data.json
# - Report: ./cc-profiler-session-2026-02-04-135044/report.html
# Open report.html in a browser to view results# Basic profiling
npx cc-profiler claude
# With correlation (extracts tool/token metadata)
npx cc-profiler --correlate-jsonl claude
# Fixed 5-minute session
npx cc-profiler --duration 5m claude
# Pass flags to Claude (note the --)
npx cc-profiler -- claude --resume abc123
# Both cc-profiler and Claude flags
npx cc-profiler --correlate-jsonl --duration 10m -- claude --dangerously-skip-permissionscc-profiler [options] [--] <command...>
| Flag | Default | Description |
|---|---|---|
--output <dir> |
Auto-generated | Output directory for session data |
--duration <time> |
None | Auto-stop after duration (e.g., 5m, 30s) |
--binary <path> |
— | Path to claude binary (overrides first arg) |
--disable-mcps |
false | Run with MCP servers disabled (A/B testing) |
--correlate-jsonl |
false | Parse Claude session JSONL to extract metadata (tool names/counts, record sizes, token counts if present) |
--turn-hotkey <spec> |
alt+t |
Manual turn marker hotkey (alt+t or off) |
--burst-idle-ms <ms> |
30 | Idle gap to end output burst detection |
--sample-interval-ms <ms> |
100 | Process sampling interval |
--interaction-timeout-ms <ms> |
2000 | Timeout for interactions with no output |
| Flag | Description |
|---|---|
--unsafe-store-paths |
Store plaintext paths in data.json |
--unsafe-store-command |
Store plaintext command + args |
--unsafe-store-errors |
Store full error messages (may contain paths) |
# Generate report from existing data
cc-profiler report <data.json> [--out <path>]
# Add marker to active session (from another terminal)
cc-profiler mark [label] [--unsafe-plaintext-label]Use -- to separate cc-profiler flags from the target command:
cc-profiler --duration 5m -- claude --dangerously-skip-permissionsEach session creates a directory containing:
| File | Description |
|---|---|
data.json |
Raw metrics (machine-readable) |
report.html |
Interactive charts (open in browser) |
markers.jsonl |
Timeline annotations |
| Metric | Description |
|---|---|
| T1 | Time from keystroke to first output byte |
| T2 | Time from keystroke to end of output burst (response complete) |
| T3 | Total output bytes in the burst |
Turn = a user message (detected when Enter is pressed, or manually via Alt+T)
| Metric | Platforms |
|---|---|
| RSS (memory) | All |
| CPU % | All |
| Page faults | Linux |
| Context switches | Linux |
| File descriptors | Linux |
| Thread count | Linux |
The HTML report includes:
- RSS + CPU over time — Memory and CPU usage throughout the session
- Turn latency over time — Response time trends (are later turns slower?)
- Turn latency vs turn index — Scatter plot of latency per turn
By default, cc-profiler produces shareable output:
- No plaintext I/O — Only timestamps and byte counts, never what you typed or received
- Hashed paths — File paths stored as SHA-256 hashes
- Redacted errors — Only error class/code, not full messages
- Names only — MCP server and plugin names (no URLs or secrets)
Optional metadata correlation:
--correlate-jsonlreads the JSONL locally and stores metadata only indata.json(no plaintext prompts/responses).
Use --unsafe-* flags only for local debugging.
Compare performance with/without MCP servers:
# Control: MCPs enabled (normal)
cc-profiler --output ./with-mcps claude
# Treatment: MCPs disabled
cc-profiler --output ./no-mcps --disable-mcps claudeThe --disable-mcps flag uses a temporary settings overlay. Your real ~/.claude/settings.json is never modified.
See CONTRIBUTING.md for development setup and guidelines.
MIT