The $47,000 invoice. The $80 overnight surprise. The "I just ran a single script" horror story. Most Claude Code users discover what their sessions cost only after the bill arrives, because the editor itself does not show a running total. The data is in the JSONL transcripts. Here is how to read it, what surprises lurk in the numbers, and what a real-time dashboard adds.
Reading the JSONL transcripts — the data is already there
Every Claude Code turn writes a record to ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl. Those records include token counts in their metadata. The information needed to compute spend per session, per model, and per account is captured by Claude Code on every turn — it is just not surfaced in any UI.
A representative assistant record contains:
{
"type": "assistant",
"model": "claude-opus-4-7-1m",
"usage": {
"input_tokens": 8421,
"cache_creation_input_tokens": 31420,
"cache_read_input_tokens": 14322,
"output_tokens": 1893
},
"ts": 1748307123000
}
Four token fields, one per pricing dimension:
input_tokens— fresh input that did not hit the cache. Billed at the highest input rate.cache_creation_input_tokens— input written to the cache for future reads. Billed at a slight premium over fresh input.cache_read_input_tokens— input read from the cache. Billed at a fraction of the fresh-input rate.output_tokens— model completion. Billed at the output rate (highest of all).
Multiply each by the per-token price for the active model, sum across all turns in a session, and you have the session's cost. The Anthropic pricing page is the authoritative source for current per-token rates. They differ by model and have changed before.
A one-liner to compute a single session's input/output token totals:
SESSION=~/.claude/projects/<encoded-cwd>/<session-id>.jsonl
jq -s '
map(select(.type == "assistant") | .usage)
| reduce .[] as $u ({input:0, cache_create:0, cache_read:0, output:0};
.input += ($u.input_tokens // 0)
| .cache_create += ($u.cache_creation_input_tokens // 0)
| .cache_read += ($u.cache_read_input_tokens // 0)
| .output += ($u.output_tokens // 0)
)
' "$SESSION"
This produces four numbers. Multiply each by your current per-token rate. Sum. That is what this session cost.
Per-model token accounting
Sessions can mix models. Claude Code's /model toggle lets you switch mid-session — Opus for complex reasoning, Sonnet for everyday work, Haiku for tool-heavy turns. The JSONL records the model used per turn. Aggregating by model requires a small change to the jq:
jq -s '
map(select(.type == "assistant") | {model, usage})
| group_by(.model)
| map({
model: .[0].model,
turns: length,
input: (map(.usage.input_tokens // 0) | add),
cache_create: (map(.usage.cache_creation_input_tokens // 0) | add),
cache_read: (map(.usage.cache_read_input_tokens // 0) | add),
output: (map(.usage.output_tokens // 0) | add)
})
' "$SESSION"
The output is an array, one entry per model. A typical heavy session looks like:
| Model | Turns | Input | Cache create | Cache read | Output |
|---|---|---|---|---|---|
| opus-4-7-1m | 8 | 12,420 | 84,231 | 412,892 | 18,402 |
| sonnet-4-6 | 22 | 31,841 | 42,103 | 1,124,332 | 28,193 |
- Sonnet ran more turns but Opus consumed more input per turn. This is typical. Heavy reasoning prompts go to Opus; lighter tool-orchestration turns go to Sonnet.
- Cache reads dominate input volume. This is structural. We will come back to it.
The dollar cost computation is per-model. Opus tokens are more expensive than Sonnet tokens, which are more expensive than Haiku tokens. Mixing models is a cost-management strategy in itself — using Opus only where its reasoning matters and Sonnet for the rest can produce significantly lower per-session spend than running Opus throughout.
Plan-tier math — Pro vs Max vs API
For subscription users, the per-token math is mostly informational. You pay a flat subscription regardless of how many tokens you push through your account. The cost-management question for Pro and Max users is not "how much did this session cost" but "am I leaving subscription value on the table" (using too little) or "am I in line to hit the 7-day cap" (using too much).
For API users, the per-token math is the bill. Every token directly translates to a dollar amount on the monthly invoice. The token totals above, run nightly against a heavy autonomous loop, are where four-figure surprise invoices come from. The dev.to writeup of the $80 overnight bill is one developer running one iterative script — they did not realize each iteration was loading 50K tokens of cached context, and the script ran 2,000 iterations before they noticed.
For mixed users (subscription for daily coding, API for fallback or batch), the relevant cost-tracking question is "which session went where." The JSONL records the active credential ID per turn. A router-aware version of the cost analysis attributes spend to the specific account or API key that served each turn, so the user can see "this session ran on the Pro subscription (no per-token cost) and this session ran on the API key (this dollar amount)."
Why the bill is usually 90% cache reads
A widely-quoted observation in the Claude Code community is that 90% of tokens in real sessions are cache reads. The example above showed exactly this pattern — over a million cache-read tokens against tens of thousands of fresh-input tokens.
The mechanism:
- Every turn replays the conversation history to the model. After ten turns, the replay is itself ten turns long.
- Prompt caching catches the static prefix (system prompt, tool definitions, eager-loaded files). The cache discount applies on every turn after the first.
- Cache reads still count as token volume. They are billed at a discount, but they appear in the token totals at full count.
For subscription users, cache reads matter for the rate-limit window (they count toward TPM) but not directly for billing. For API users, cache reads are real money — cheaper than fresh reads, but not free.
The cost-optimization implication for API users is to keep sessions tight. A session with one hundred turns has replayed history one hundred times. A session with three turns has replayed it three times. Both can solve a problem; the long session costs ten to thirty times more in cache reads alone.
For senior developers running autonomous loops, this is the lever that matters. The loop architecture — does it reset context between iterations, or does it carry context forward — is the single largest determinant of monthly API spend. Resetting context is cheaper in cache reads. Carrying context forward is cheaper in fresh inputs (less re-loading of the same files). The choice has to fit the workload.
Or: a UI for it
The jq workflows above work for one-off analysis. They do not work for daily awareness. A developer running Claude Code for hours a day cannot pause to run a jq command every time they want to know how the budget looks.
A productized dashboard solves the awareness problem. The shape that works:
- Per-session running total. Updated live as turns land. Shows fresh-input, cache-create, cache-read, and output tokens for the active session, plus the dollar cost (or "subscription — no per-token cost" if running on Pro or Max).
- Per-day total across all sessions. Aggregates everything on this account today.
- Per-account breakdown across the pool. If you are running a multi-account pool, the dashboard shows which account absorbed which fraction of today's spend.
- Cap-hit recommender. Combines current usage with the rolling 5-hour and 7-day windows to estimate "you are this many turns away from hitting the cap."
- Subscription savings calc. For users running pooled subscriptions, an estimate of what the same workload would have cost on the API at current rates. This is the dollar value of running on subscription instead of pay-as-you-go.
The dashboard we ship in the VS Code sidebar is free to download and try, no credit card needed, so the running total is in front of you before the workload gets expensive rather than after. You can start the 7-day free trial and start tracking today, or open the cost dashboard, per-account attribution, and cap-hit recommender on the 14-day Premium Trial — $0 today, cancel anytime before day 15.
The dashboard does not change your billing. It changes your awareness. Most surprise invoices come from running a workload at a cost the user did not know about. A live dashboard turns the $80 overnight bill into a $4 evening prompt and an $80 morning decision to either continue or stop.
Frequently asked questions
Does Claude Code show me my token usage anywhere in the editor?
Not directly. The CLI's /usage command surfaces a coarse summary; the VS Code extension does not currently have a usage UI. The data is in the JSONL transcripts at full per-turn granularity. Third-party dashboards parse the transcripts to show real-time usage.
Why are cache reads so much of my token total?
Because every turn replays the conversation history, and the cached prefix (system prompt, tool definitions, recently-read files) is included in that replay. After ten turns, the same cached prefix has been read ten times. After fifty turns, fifty times. Cache reads are billed at a discount, but they accumulate fast.
Will switching from Opus to Sonnet mid-session save money?
For API users, yes. Sonnet's per-token price is lower than Opus across all four dimensions. For subscription users, the model choice does not change the bill — but it does affect the 5-hour and 7-day budget burn, because heavier models tend to produce longer completions per turn. Mixing models is a budget management strategy in both cases.
Can I cap my API spend at a hard dollar amount per day?
Anthropic's API supports usage limits at the organization level. They are coarse (typically per-month, with some per-day options). For finer control, a proxy in front of the API can refuse requests after a configurable daily spend. The proxy approach gives you per-session, per-project, or per-account caps.
Does prompt caching cost extra to set up?
Cache creation is billed at a small premium over fresh input — typically 25% more per token. The cache then serves subsequent reads at a fraction of the fresh-input rate. The break-even point is usually one or two cached reads. For sessions that read the same prefix more than twice, caching is cheaper. For one-shot prompts, caching is slightly more expensive.
What developers are reporting
Usage visibility is, by the maintainers' own triage, the single most-requested feature category: GitHub issue #33978 consolidates 10+ open requests and notes "token usage visibility is the #1 most-requested feature category in Claude Code issues." A live meter and per-project odometer answer that demand directly.
Closing
The cost data is already in your transcripts. The question is whether you want to read it once a month, when the invoice arrives, or in real time as the session is happening. The cost analytics dashboard we ship is the productized version of the jq workflows above, running live in the VS Code sidebar.
If you want the live total on your own sessions, the 14-day Premium Trial is $0 today and you can cancel anytime before day 15 — it adds the cost dashboard, per-account attribution, and the cap-hit recommender on top of rotation. Not ready to add a card? Install Power Claude Free instead: the 7-day free trial gives you full Pro access, no credit card.