Files
ai-agent/docs/usage-calibration.md
Gabriel Vidal da23d22519 feat(scripts): usage-calibration — fit /usage % against transcript spend
Lines the plan windows' official percentages (HA sensors from the homelab's
claude-usage-notifier) up against the account's archived token spend, priced
at list price, and fits dollars-per-1% for the 5h and week windows plus a
Fable multiplier. docs/usage-calibration.md records the method and the
2026-10 calibration (1% week ≈ $22, 1% 5h ≈ $5.6, Fable ×1.75, no separate
Fable bucket) and notes that pricing.py overstates the newest models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:40:14 +02:00

4.3 KiB
Raw Permalink Blame History

What 1 % of a Claude plan window is worth

Claude Code's /usage shows how full the subscription's windows are (rolling 5 h, 7-day week), as whole percentages. The transcripts show what was spent, in tokens. scripts/usage-calibration.py lines the two up and fits the exchange rate, so a dollar figure on the dashboard can be read as "% of my week", and the plan's ceiling can be expressed in tokens.

uv run scripts/usage-calibration.py                           # personal seat, last 9 days
uv run scripts/usage-calibration.py --since 2026-09-13 --json /tmp/cal.json
uv run scripts/usage-calibration.py --account work --prefix sensor.claude_work_usage

Inputs

  • Usage %: Home Assistant long-term statistics (hourly min/max) of the sensors that the homelab's claude-usage-notifier pushes (<prefix>_5h, _week, _fable). The script reads the recorder SQLite db read-only, so it goes back to the sensors' creation, beyond the 10-day state history.
  • Tokens: the account's conversations listed by /api/conversations?account= (the backend resolves each conversation's account), parsed from the archive, subagents included. Records are de-duplicated on (message id, request id) and priced at list price (the script's own table; see "Pricing" below).

Method

The data is binned by hour. A window's % only rises between resets, so each bin's increase is the usage spent in it. Bins that contain a reset are dropped, and so are 5 h bins above 100 % (overage). The fit is Δ% = k·cost + c, by non-negative least squares. c soaks up usage the archive can't see (claude.ai, the desktop app, a Mac that isn't paired as a worker). It came out at ≈ 0 once both Macs were paired.

Unweighted list-price dollars leave a drift. Through a Fable-heavy week the cumulative $/% climbed from $13.5 to $20 as the mix moved to Opus. A Fable multiplier removes it. It is chosen by grid search on the combined R² of the 5 h and week fits, and with it the cumulative ratio stays flat at $21–23/%. Other weightings were tested and lost: cache reads free, cache reads at 0.1× input, cache reads at 1× input, Opus 5.5 priced as Opus 5, and raw token counts.

Use 1 h bins. With 3 h bins most 5 h resets fall inside a bin, which then gets dropped, and the 5 h fit collapses.

Calibration — personal Max plan (€200/month), 2026-10-12

Window: 2026-10-04 18:00 → 2026-10-12 (Opus 5.5 / Fable 5.1 era), 1 h bins. Intervals are 90 % CIs from a 300-draw day-block bootstrap.

API $ at list price tokens at the real Opus 5.5 mix¹
1 % of the 5 h window $5.6 [5.4–6.8] ≈ 17 Mtok
1 % of the week $22.1 [21.1–24.6] ≈ 68 Mtok
Fable multiplier ×1.75 [1.6–2.5]: 1 % week ≈ $13 of Fable 5.1 ≈ 14 Mtok of Fable¹
full 5 h window ≈ $560 ≈ 25 % of a week
full week ≈ $2,200 ≈ 6.8 Gtok
100 % of every week for a month (×4.35) ≈ $9,600 (≈ $5,700 if all Fable) ≈ 30 Gtok

¹ Agentic Claude Code traffic is 98 % cache reads by tokens. On Opus 5.5 they are about 61 % of the dollars, cache writes 32 % and output 8 %. The same 1 % of the week buys ≈ 1.1 M Opus 5.5 output tokens, or 5.5 M fresh input, or 110 M cache reads.

  • No separate Fable bucket. The seven_day_<model> key never appeared in the status line's rate_limits from 2026-07-17 to 2026-10-12, despite heavy Fable 5 and Fable 5.1 use. Fable draws on the same 5 h and week windows, about 1.75× faster per list-price dollar than Opus 5.5.
  • The week binds, not the 5 h window. A full 5 h window is ≈ 25 % of the week, and a week has 33.6 of them.
  • Earlier eras differ. In Jul–Aug (Opus 4.8 / Opus 5 / Fable 5), unweighted fits gave ≈ $30 per 1 % of the week. Limits and prices move with model launches, so re-run the script after one.

Pricing: the backend overstates current models

backend/conversations/pricing.py predates the latest price cuts. It prices every Opus at $5/$25 with a flat 0.1× cache read, so Opus 5.5 ($4/$20, cache read $0.20) comes out ≈ 2× too high. It prices Fable 5.1 cache reads at $1.00 (list $0.25), Sonnet 5/5.5 at $3/$15 (list $2/$10), and Haiku 5.5 at $1/$5 (list $0.10/$0.50). Across 2026-09-13 → 10-12 the dashboard's personal total is ≈ 1.9× list price. In the dashboard's own dollars, 1 % of the week ≈ $44.5 and 1 % of 5 h ≈ $11.2.