fuzzyworld

fuzzyworld-tools / files / docs / usage.md

usage.md

Blame: the commit that last changed each line · file · history

bb7e1f57 2026-11-06 Pavel Safronov1# Claude Code usage: trailers, costs and charts
2
3A commit message can carry a Claude Code session's running token tally as git trailers. The code site reads them to
4show usage per commit, per session and per week, per repo (`/<name>/usage/`) and across all public repos (`/usage/`).
5
6## Writing the trailers
7
8```bash
9npm run prepare-usage-for-pr # same as: fw usage --trailers (python3 lib/usage.py --trailers)
10```
11
12`fw usage` also reads Claude Code's transcripts in `~/.claude/projects` for other views:
13
14| Command | Prints |
15|---|---|
16| `fw usage` | token use per session of this project: messages, current context size, cache-read, output (cache-read and output include subagents) |
17| `fw usage --all` | the same for every project |
18| `fw usage --now` | one line for the newest session, to decide when to put it down |
19| `fw usage --trailers [--session ID]` | the commit-message trailers for the newest session here, or the one named. It warns on stderr when that transcript is over 10 minutes old |
20
21## The trailers
22
23| Trailer | Meaning |
24|---|---|
25| `FW-Tokens-In`, `FW-Tokens-Out`, `FW-Tokens-Cached` | exact integers |
26| `FW-Tokens-Method: 2` | how the count was made (see "Older commits") |
27| `FW-Model-Tokens: <model> in=… out=… read=… write5m=… write1h=…` | one line per model, so a cost can be computed |
28| `FW-Session` | the session id, for provenance only |
29| `FW-Rtk-Saved`, `FW-Rtk-Cmds` | rtk's lifetime savings; not read by the site |
30
31Notes on `FW-Model-Tokens`: requests with a prompt over 100K tokens on a model with a higher tier are filed under
32`<model>@over100k`; a cache write without a 5m/1h split is counted as 5m.
33
34### Older commits
35
36- **Method 1** (no `FW-Tokens-Method`): that `jq` count double counted repeated transcript lines (roughly 1.5-2× too high) and missed subagents. They are left as written, shown with tokens but with the cost unknown.
37- **Rounded `Usage:` line** (even older): `Usage: 10.6K in / 101.3K out / 5.1M cached (session tally)`. Still read. Steps between such lines are only known to within the rounding (about two tenths of K/M/G), so small ones show as ≈0.
38- A commit without a trailer shows no bar.
39
40## How the site reads them
41
42- **A commit's cost** is the step from the previous tally. A new session starts when a tally (or any model's counter) falls, or the method changes.
43- **Dollar figures are estimates.** `server/prices.json` holds the list prices per model (with an `as_of` date), and the page says "estimated API list-price equivalent, not what was paid".
44- **"AI-marked"** means an AI `Co-Authored-By` trailer or a usage trailer. A commit without one is "no AI marker", not "human" (see Provenance in [PLAN.md](../PLAN.md)).
45
46## What the pages show
47
48**The commit log** has a bar of output tokens per commit, highlighted at 2× the median or more. Each commit page
49shows its step, estimated cost and the session tally.
50
51**`/<name>/usage/`** ranks commits, totals sessions (with an estimated cost per session, "unknown" unless every
52commit in it has one) and draws five charts, per week (per month for histories over 104 weeks):
53
541. output tokens,
552. estimated cost,
563. cached reads,
574. average cost per commit (the tooltip gives n),
585. AI-marked commits: two lines, all commits and AI-marked ones.
59
60In the token and cost charts, hatched means commits without usage data or without a known cost: unknown, rather
61than zero. The AI-marked chart has no hatching.
62
63**`/usage/`** rolls the same up over the public published repos, with a table of one row per repo. A repo's cost
64shows "(n of m commits)" when only some commits have a known cost. Charts start at the first AI-marked commit; dates
65before 2000 or after tomorrow are ignored.
66
67### How it is built
68
69`/usage/` is rebuilt on every `fw publish`, from a small per-repo summary that `build_repo` saves in the state dir
70(`<name>.usage.json`, keyed by the repo's HEAD), so it does not re-run `git log` for every repo.