/usage2
For Claude subscription users (Pro / Max 5x / Max 20x). The dollar figures are API-equivalent (what you would have paid on metered API). You actually pay the flat subscription fee.
Why this exists: so the agent can self-assess its own token efficiency, plan effective session usage, and make token spend predictable — not just watch a number climb. With this skill the agent can answer "how much session budget is left", "what will this action cost", and "is approach A cheaper than approach B" without the user babysitting a panel.
Three capabilities in one skill:
- Token meter (~10ms) — reads the session transcript JSONL and reports authoritative per-action token consumption, API-equivalent dollar cost, cache breakdown, per-subagent attribution.
- Quota panel (~12s, cached for 10 min) — captures Claude Code's built-in
/usage panel via tmux for rolling 5h / 7d / Sonnet-only meters with reset times.
- Calibration — learns your tier's tokens-per-percent passively from each
quota capture. After 2+ samples you can estimate "this 50K-token action will be ~X% of my session."
Token budgets (Max 20x, measured 2026-05-19)
Empirical priors so the agent can reason about budget immediately — before any calibration. One 5-hour session window at 100% panel saturation, single-model strategy:
| Model |
Session cap |
$/pp |
output tokens/pp |
cache_read tokens/pp |
| Haiku 4.5 |
~$44 |
$0.443 |
56,190 |
1,122,644 |
| Sonnet 4.6 |
~$46 |
$0.464 |
23,067 |
219,383 |
| Opus 4.7 |
~$50 |
$0.499 |
11,817 |
131,527 |
pp = 1 percentage-point of the /usage session window. The panel is approximately model-neutral — $/pp differs by at most ~13% across models. Per-call cost (2000-word generation over a ~62K-token cached prefix): cold $0.10 / $0.21 / $0.54, hot $0.02 / $0.08 / $0.24 for Haiku / Sonnet / Opus.
These are priors (Max 20x measured directly; Pro and Max 5x are linearly scaled, untested) and hold until Anthropic changes limits. meter.py budget prints the full per-bucket table; meter.py sample twice calibrates against your own account. Full methodology: research/per_model_cost_v5.md.
First-time setup
python3 ${CLAUDE_SKILL_DIR}/meter.py tier max20x # or pro / max5x
python3 ${CLAUDE_SKILL_DIR}/meter.py sample # first calibration sample
(Sample again ~15 min later to derive slopes.)
Invocation
python3 ${CLAUDE_SKILL_DIR}/meter.py [mode] [args]
Modes:
| Mode |
Purpose |
Cost |
summary (default) |
Tokens + $ + % session + % week + calibration + signals |
~12s* |
quick |
One-line: tokens · $ · cache% · session% · week% |
~10ms |
agents |
Per-subagent attribution: agentType, $, prompt preview |
~10ms |
mark <name> [--quota] |
Save a checkpoint, optionally with a quota snapshot |
~10ms / ~12s |
since <name> |
Token + $ + quota delta since checkpoint |
~10ms |
marks |
List saved checkpoints |
~1ms |
drop <name> |
Delete a checkpoint |
~1ms |
raw |
JSON dump of everything (for downstream tools) |
~10ms |
quota |
Force-refresh quota panel + show parsed result |
~12s |
sample |
Take a calibration sample (forces quota capture) |
~12s |
calibrate |
Show calibration history + derived tokens-per-percent estimates |
~1ms |
calibrate-account-scope |
Consecutive-pair $/pp slopes from short-interval samples |
~1ms |
estimate --model <m> --tokens <N> |
$ + est. session/week % impact for a planned action |
~1ms |
budget |
Empirical session token budget for your tier (caps, $/pp, tokens/pp) |
~1ms |
reset-calibration |
Archive all reports to reports_archive/<timestamp>/ |
~10ms |
tier [<t>] |
Show or set subscription tier (pro / max5x / max20x) |
~1ms |
* The cached quota result is reused for 10 minutes, so consecutive summary calls within that window are ~10ms.
A/B comparison workflow
For settling questions like "native-resolution image vision request vs resize to 1024×1024 — which costs fewer tokens?":
python3 meter.py mark approach-A --quota
# ... agent does approach A ...
python3 meter.py since approach-A
python3 meter.py mark approach-B --quota
# ... agent does approach B ...
python3 meter.py since approach-B
since reports tokens + dollars + percentage-point delta on each quota window.
Output anatomy
A full summary reports:
- Main thread — turns, tool calls, input/output/cache split, per-model breakdown, API-equivalent dollars, avg-per-turn
- Subagents — grouped by
agentType, with assumed model (default mapping: Explore→Haiku, general-purpose→Sonnet), per-spawn dollars and prompt preview
- Grand total — tokens + dollars
- Tier context — "this session = N days of your subscription fee in API-equivalent value"
- Rolling quota windows — session 5h, week (all models), week (Sonnet only) with reset times, age of the cached reading
- Calibration — once you have ≥2 samples: tokens-per-percent and estimated full-window capacity
- Efficiency signals — cache hit ratio (good ≥80%, churning <50%), output/input ratio, per-turn growth trend
Autonomous self-throttling
Tell the agent at the start of a long autonomous run:
Every 10 minutes, run /usage2 quick. If session reaches 75% or grand-total grows by more than 500K tokens since the last check, pause and report. If cache hit ratio drops below 60%, also pause — something is invalidating the cache.
quick is ~10ms (uses cached quota). It's free to poll.
How calibration works
Each time you run sample (or any mode that refreshes the quota panel), the meter records:
- Current %s for the three quota windows
- The trailing 5h and 7d token totals (weighted by API-rate ratios into "input-equivalent" units)
From ≥2 samples, the meter computes tokens-per-percent for each window. With this you can:
- See your tier's effective rolling-window capacity
- Estimate the % impact of a planned action before doing it
- Spot anomalies (a sudden jump in % with little token usage usually means the panel reset)
Anthropic doesn't publish exact per-tier token caps — calibration is how usage2 learns them empirically.
Caveats
- The current in-flight turn isn't yet in the JSONL. Claude Code writes assistant messages after the turn completes. The meter is always one turn behind.
- Subagents are aggregated, not per-step.
toolUseResult.totalTokens gives the full cost of a subagent dispatch, but the parent transcript doesn't include the subagent's internal turn-by-turn detail. Subagent costs assume a model per agentType (see AGENT_TYPE_MODEL in meter.py).
- Agent-tool tax (per-model isolation impossible via subagents). Every Agent dispatch — foreground OR background — writes the subagent's return into the parent's next-turn
cache_write_1h at the parent's model rate (Opus, for interactive sessions). The displayed subagent cost is only the subagent's own tokens; the parent-side amplification is typically 10–30× more and shows up in the main-thread total. For per-model A/B testing, use claude -p --model X subprocesses, not the Agent tool — run them sequentially, since parallel runs inflate cost via redundant cache writes. Demonstrated empirically in research/per_model_cost_v5.md.
- Background subagents are invisible to
agents mode. run_in_background: true Agent dispatches don't write toolUseResult.totalTokens to the parent JSONL. They still consume quota (the panel ticks) but /usage2 agents can't see them. Use foreground dispatch when you need per-spawn attribution.
- Date-suffixed model names (e.g.,
claude-haiku-4-5-20251001) fall back to Sonnet pricing. claude -p subprocesses sometimes write the full versioned model ID into their JSONL. The meter's rates_for() does a strict dict lookup and falls back to DEFAULT_RATE_KEY (Sonnet) for unknown keys, mis-attributing Haiku cost as Sonnet (3× higher). When using claude -p for measurement, trust the subprocess's stdout total_cost_usd directly — that's Anthropic's billing source of truth.
- Hooks aren't separately attributed. PostToolUse / PreCompact hooks that inject context show up in the next assistant turn's input count, not as their own line.
- Quota panel scrape spawns a real
claude process. No LLM tokens, but ~12s of latency. The 10-min cache amortizes this.
- Subscription tier display vs reality. The "days of subscription fee" line is informational — it doesn't represent your actual cost (which is the flat monthly fee), it represents the API-equivalent value of what you consumed.
- API rates can shift.
RATES is hardcoded in meter.py — update when Anthropic publishes new pricing.
Failure modes
ERR: no JSONL found for project slug '...' — fresh project with no transcript yet, or CC's slug-naming convention drifted.
ERR: could not capture /usage panel — see capture.sh for tmux scrape failure modes.
- Calibration estimates wrong/wild — too few samples, or all samples are within the same quota window since reset. Take more samples across longer time spans.
1---2name: usage23description: For Claude Code SUBSCRIPTION users (Pro / Max 5x / Max 20x) — give the agent visibility into its own token consumption with API-equivalent dollar cost, % of session/week quota, and per-subagent attribution. Reads Claude Code's per-message `usage` blocks from the session transcript JSONL. Captures the built-in `/usage` panel via tmux for rolling 5h/7d/Sonnet-only quota percentages. Includes a passive calibration that learns your tier's tokens-per-percent from real samples. Use when the user says "/usage2", "how many tokens", "token cost", "compare token usage", "am I being efficient", "what's my quota", "how close to the limit", "subagent cost", "which subagent burned the most", or whenever the agent needs to reason about session/week budget, model efficiency, or A/B token comparisons.4---56# /usage278For **Claude subscription users** (Pro / Max 5x / Max 20x). The dollar figures are *API-equivalent* (what you would have paid on metered API). You actually pay the flat subscription fee.910**Why this exists:** so the agent can *self-assess its own token efficiency, plan effective session usage, and make token spend predictable* — not just watch a number climb. With this skill the agent can answer "how much session budget is left", "what will this action cost", and "is approach A cheaper than approach B" without the user babysitting a panel.1112Three capabilities in one skill:13141. **Token meter** (~10ms) — reads the session transcript JSONL and reports authoritative per-action token consumption, API-equivalent dollar cost, cache breakdown, per-subagent attribution.152. **Quota panel** (~12s, cached for 10 min) — captures Claude Code's built-in `/usage` panel via tmux for rolling 5h / 7d / Sonnet-only meters with reset times.163. **Calibration** — learns your tier's tokens-per-percent passively from each `quota` capture. After 2+ samples you can estimate "this 50K-token action will be ~X% of my session."1718## Token budgets (Max 20x, measured 2026-05-19)1920Empirical priors so the agent can reason about budget immediately — before any calibration. One 5-hour session window at 100% panel saturation, single-model strategy:2122| Model | Session cap | $/pp | output tokens/pp | cache_read tokens/pp |23|------------|-------------|--------|------------------|----------------------|24| Haiku 4.5 | ~$44 | $0.443 | 56,190 | 1,122,644 |25| Sonnet 4.6 | ~$46 | $0.464 | 23,067 | 219,383 |26| Opus 4.7 | ~$50 | $0.499 | 11,817 | 131,527 |2728`pp` = 1 percentage-point of the `/usage` session window. The panel is approximately model-neutral — $/pp differs by at most ~13% across models. Per-call cost (2000-word generation over a ~62K-token cached prefix): cold $0.10 / $0.21 / $0.54, hot $0.02 / $0.08 / $0.24 for Haiku / Sonnet / Opus.2930These are priors (Max 20x measured directly; Pro and Max 5x are linearly scaled, untested) and hold until Anthropic changes limits. `meter.py budget` prints the full per-bucket table; `meter.py sample` twice calibrates against your own account. Full methodology: `research/per_model_cost_v5.md`.3132## First-time setup3334```bash35python3 ${CLAUDE_SKILL_DIR}/meter.py tier max20x # or pro / max5x36python3 ${CLAUDE_SKILL_DIR}/meter.py sample # first calibration sample37```3839(Sample again ~15 min later to derive slopes.)4041## Invocation4243```bash44python3 ${CLAUDE_SKILL_DIR}/meter.py [mode] [args]45```4647Modes:4849| Mode | Purpose | Cost |50|---------------------|------------------------------------------------------------------|--------|51| `summary` (default) | Tokens + $ + % session + % week + calibration + signals | ~12s\* |52| `quick` | One-line: tokens · $ · cache% · session% · week% | ~10ms |53| `agents` | Per-subagent attribution: agentType, $, prompt preview | ~10ms |54| `mark <name>` `[--quota]` | Save a checkpoint, optionally with a quota snapshot | ~10ms / ~12s |55| `since <name>` | Token + $ + quota delta since checkpoint | ~10ms |56| `marks` | List saved checkpoints | ~1ms |57| `drop <name>` | Delete a checkpoint | ~1ms |58| `raw` | JSON dump of everything (for downstream tools) | ~10ms |59| `quota` | Force-refresh quota panel + show parsed result | ~12s |60| `sample` | Take a calibration sample (forces quota capture) | ~12s |61| `calibrate` | Show calibration history + derived tokens-per-percent estimates | ~1ms |62| `calibrate-account-scope` | Consecutive-pair $/pp slopes from short-interval samples | ~1ms |63| `estimate` `--model <m> --tokens <N>` | $ + est. session/week % impact for a planned action | ~1ms |64| `budget` | Empirical session token budget for your tier (caps, $/pp, tokens/pp) | ~1ms |65| `reset-calibration` | Archive all reports to `reports_archive/<timestamp>/` | ~10ms |66| `tier [<t>]` | Show or set subscription tier (pro / max5x / max20x) | ~1ms |6768\* The cached quota result is reused for 10 minutes, so consecutive `summary` calls within that window are ~10ms.6970## A/B comparison workflow7172For settling questions like *"native-resolution image vision request vs resize to 1024×1024 — which costs fewer tokens?"*:7374```bash75python3 meter.py mark approach-A --quota76# ... agent does approach A ...77python3 meter.py since approach-A7879python3 meter.py mark approach-B --quota80# ... agent does approach B ...81python3 meter.py since approach-B82```8384`since` reports tokens + dollars + percentage-point delta on each quota window.8586## Output anatomy8788A full `summary` reports:8990- **Main thread** — turns, tool calls, input/output/cache split, per-model breakdown, API-equivalent dollars, avg-per-turn91- **Subagents** — grouped by `agentType`, with assumed model (default mapping: Explore→Haiku, general-purpose→Sonnet), per-spawn dollars and prompt preview92- **Grand total** — tokens + dollars93- **Tier context** — "this session = N days of your subscription fee in API-equivalent value"94- **Rolling quota windows** — session 5h, week (all models), week (Sonnet only) with reset times, age of the cached reading95- **Calibration** — once you have ≥2 samples: tokens-per-percent and estimated full-window capacity96- **Efficiency signals** — cache hit ratio (good ≥80%, churning <50%), output/input ratio, per-turn growth trend9798## Autonomous self-throttling99100Tell the agent at the start of a long autonomous run:101102> Every 10 minutes, run `/usage2 quick`. If session reaches 75% or grand-total grows by more than 500K tokens since the last check, pause and report. If cache hit ratio drops below 60%, also pause — something is invalidating the cache.103104`quick` is ~10ms (uses cached quota). It's free to poll.105106## How calibration works107108Each time you run `sample` (or any mode that refreshes the quota panel), the meter records:109110- Current %s for the three quota windows111- The trailing 5h and 7d token totals (weighted by API-rate ratios into "input-equivalent" units)112113From ≥2 samples, the meter computes tokens-per-percent for each window. With this you can:114115- See your tier's effective rolling-window capacity116- Estimate the % impact of a planned action before doing it117- Spot anomalies (a sudden jump in % with little token usage usually means the panel reset)118119Anthropic doesn't publish exact per-tier token caps — calibration is how `usage2` learns them empirically.120121## Caveats122123- **The current in-flight turn isn't yet in the JSONL.** Claude Code writes assistant messages after the turn completes. The meter is always one turn behind.124- **Subagents are aggregated, not per-step.** `toolUseResult.totalTokens` gives the full cost of a subagent dispatch, but the parent transcript doesn't include the subagent's internal turn-by-turn detail. Subagent costs assume a model per `agentType` (see `AGENT_TYPE_MODEL` in `meter.py`).125- **Agent-tool tax (per-model isolation impossible via subagents).** Every Agent dispatch — foreground OR background — writes the subagent's return into the parent's next-turn `cache_write_1h` at the parent's model rate (Opus, for interactive sessions). The displayed subagent cost is only the subagent's own tokens; the parent-side amplification is typically 10–30× more and shows up in the main-thread total. **For per-model A/B testing, use `claude -p --model X` subprocesses, not the Agent tool — run them sequentially, since parallel runs inflate cost via redundant cache writes.** Demonstrated empirically in research/per_model_cost_v5.md.126- **Background subagents are invisible to `agents` mode.** `run_in_background: true` Agent dispatches don't write `toolUseResult.totalTokens` to the parent JSONL. They still consume quota (the panel ticks) but `/usage2 agents` can't see them. Use foreground dispatch when you need per-spawn attribution.127- **Date-suffixed model names (e.g., `claude-haiku-4-5-20251001`) fall back to Sonnet pricing.** `claude -p` subprocesses sometimes write the full versioned model ID into their JSONL. The meter's `rates_for()` does a strict dict lookup and falls back to `DEFAULT_RATE_KEY` (Sonnet) for unknown keys, mis-attributing Haiku cost as Sonnet (3× higher). When using `claude -p` for measurement, trust the subprocess's stdout `total_cost_usd` directly — that's Anthropic's billing source of truth.128- **Hooks aren't separately attributed.** PostToolUse / PreCompact hooks that inject context show up in the next assistant turn's input count, not as their own line.129- **Quota panel scrape spawns a real `claude` process.** No LLM tokens, but ~12s of latency. The 10-min cache amortizes this.130- **Subscription tier display vs reality.** The "days of subscription fee" line is informational — it doesn't represent your actual cost (which is the flat monthly fee), it represents the API-equivalent value of what you consumed.131- **API rates can shift.** `RATES` is hardcoded in `meter.py` — update when Anthropic publishes new pricing.132133## Failure modes134135- `ERR: no JSONL found for project slug '...'` — fresh project with no transcript yet, or CC's slug-naming convention drifted.136- `ERR: could not capture /usage panel` — see `capture.sh` for tmux scrape failure modes.137- Calibration estimates wrong/wild — too few samples, or all samples are within the same quota window since reset. Take more samples across longer time spans.