It's not the thinking: where four months of my Claude Code usage went
Claude Code 2.1.306 · dollar amounts are what the same usage would cost at API prices; I pay a flat monthly Claude subscription (Method)
I use Claude Code on a monthly Claude subscription, and in heavy multi-agent weeks my weekly limit ran out in about a day. I assumed the culprits were --effort max and running Opus everywhere. Instead of guessing, I priced every API request in my local transcripts: 110,180 requests over four months, about $14.2K at API prices.
Thinking turned out to be 7% of it. Nearly all the rest was the prompt cache: re-reading big contexts on every turn, and re-writing them from scratch whenever they sat idle past their cache lifetime. Claude Code 2.1.286 started compacting large idle sessions by itself, which fixes the smaller part of that: main sessions left idle were about 8% of my usage. The bigger part, subagents and big contexts, is still up to you. Below is what I measured, how Claude Code’s cache behaves (checked against the official docs and my own transcripts), and what I changed.
TL;DR
- Output, including thinking, was 7% of usage. Reading cached context was 53%, writing it to the cache 40%.
- Subagents were 57%. A few long-lived ones dominated: agents whose context grew past 500K tokens were 17% of agents and 64% of subagent usage.
- About 26% was avoidable cache rebuilds. Subagents get a 5-minute cache. A subagent holding 400K tokens that waits 10 minutes for a test suite writes all 400K again on its next turn.
- The main session gets a 1-hour cache on a subscription, and my transcripts confirm it: 95% cache hits after up to 55 minutes idle, 96% rebuilds after 65.
- Claude Code now handles idle main sessions. Since 2.1.286 it compacts an idle session over 200K tokens before its 1-hour cache expires. In my data idle main sessions were ≈$1.1K, 8% of usage, nearly all of it above 200K. Subagent rebuilds were nearly twice that, and nothing compacts those for you.
- What I changed: small disposable agents, and nobody waits inside a big context. In the week after, avoidable rebuilds fell from 26% to 5% of usage, and the cost per request halved.
How Claude Code’s cache works
Every request sends the whole conversation. The part that is already cached is billed as a cache read; anything new is written to the cache. From Anthropic’s pricing and prompt caching docs:
| Per million tokens | Opus 5.5 | Sonnet 5.5 |
|---|---|---|
| Input | $4 | $2 |
| Cache read | $0.20 | $0.10 |
| Cache write, 5-minute lifetime | $5 (1.25× input) | $2.50 |
| Cache write, 1-hour lifetime | $8 (2× input) | $4 |
| Output, including thinking | $20 | $10 |
Who gets which lifetime:
- The main conversation: 1 hour on a Claude subscription, within plan usage. 5 minutes on usage credits, an API key or a cloud provider.
- Everything else (subagents, agent-team teammates, forks, workflows, compaction): 5 minutes.
- Every cache hit resets the clock. Once it runs out, the next request writes the entire context again.
So usage grows with context size × turns, plus a full re-write every time a big context sits idle past its lifetime. Reading 400K cached tokens on Opus 5.5 costs $0.08; writing them again with a 1-hour lifetime costs $3.20.
Since 2.1.286, Claude Code also compacts an idle main session about 54 minutes after its last request, shortly before the 1-hour cache expires, if its context is over 200K tokens and it runs in a terminal; the transcript logs “Compacted while idle, before the prompt cache expired”. The 2.1.299 changelog documents it, and "idleCompaction": false in settings (or its row in /config) turns it off. #98747 discussed the trade-off and led to that opt-out: it saves the re-cache but drops working detail from long sessions.
For the current session, /cost shows the cache hit ratio, misses and their likely causes, and /usage shows whether the main cache is warm; a status-line script gets the same as JSON (prompt_cache). None of them shows the picture across sessions and subagents, which is what the rest of this post is about.
Method
- Data: every transcript under
~/.claude/projects, including the subagent transcripts in each session’ssubagents/folder (a non-recursive glob misses them). 997 files (62 sessions, 935 subagent transcripts), 110,180 API requests, June 11 to October 12, 2026, all from my own machine. - One record per API request. Claude Code logs several entries per response, so records are deduplicated by message and request ID. Each has uncached input, cache reads, cache writes split by 5-minute and 1-hour lifetime, and output.
- Priced at API list prices. I pay a flat monthly subscription, not these amounts. This “API-equivalent” figure is a proxy for how fast a plan limit drains. Anthropic says cache reads still count against plan usage but doesn’t publish the weights, so treat the dollar amounts as relative, not as a bill.
- A rebuild is a request that writes again what the previous request had already cached: at least 1,000 tokens it could have read back but had to rewrite. The first request of each transcript (a cold start) and compactions are counted apart. Its avoidable premium is what rewriting those tokens cost minus what they would have cost as cache reads. A simpler rule (at least 20K tokens and half the prompt written) gives nearly the same total: 26.5% instead of 25.9%.
- The numbers come from claude-cache-audit, which reproduces my original scripts exactly.
- Prior work.
- The Register covered the 1-hour vs 5-minute lifetimes in April.
- #46829 traced the March TTL change.
- #66115 worked out the cost model for compacting idle sessions.
- cachemiss lists every rebuild with its reason, cost and the subagent behind it, and ctxprof profiles sessions from a status-line heartbeat and totals idle-rebuild waste across sessions.
What’s new here: subagents over four months, the 1-hour subagent break-even, and before/after numbers.
Finding 1: thinking was 7%
| Where the usage went | Share |
|---|---|
| Reading cached context | 53% |
| Writing context to the cache | 40% |
| Output, including thinking | 7% |
| Uncached input | ~0% |
84% of usage was on requests with more than 200K tokens of context, and 58% on more than 400K. An Opus 5.5 main-session turn cost about $0.10 at 100–300K context and about $0.28 above 600K.
I ran --effort max the whole time, and every subagent inherited it, even the Sonnet ones. In tool loops, thinking per turn stayed small. The things I’d have blamed first, the effort level, the advisor tool and the occasional Fable turn, together came to under 3% of usage.
Finding 2: a few long-lived subagents were most of it
Subagents were 57% of usage. Starting one is cheap, about 38K tokens or $0.10–0.20. Keeping one around is what costs:
- Agents whose context peaked above 500K were 17% of agents and 64% of subagent usage. Agents that finished in under 30 turns were 4%.
- With agent teams on, every named subagent launches as a long-lived teammate. Teammates were 72% of subagent usage (460 transcripts, ≈$5.9K), against ≈$1.8K for 380 plain subagents and ≈$0.5K for 94 forks.
- Most of it came from one project I built with agent teams (≈$6.2K). 371 named spawns were reused through 1,417 messages. 37 teammates ran more than 300 turns with a median peak context of 961K tokens; they alone were 53% of that project’s subagent usage. Agents that stayed under 250K cost 5%.
The docs do warn that agent teams use “approximately 7x more tokens than standard sessions when teammates run in plan mode”. What I hadn’t appreciated is why: a teammate that keeps getting new tasks keeps its whole history, and re-reads it on every turn.
Forks start cheap (a fork’s first request reused ~122K of the parent’s cache), but every later turn re-reads that inherited context too.
Finding 3: a quarter went to cache rebuilds
Avoidable rebuilds came to ≈$3.7K, 26% of all usage (about 30% in the agent-teams project).
Subagents that waited. When a subagent holding ~400K of context ran something that took longer than 5 minutes (a test suite, an end-to-end harness, a poll loop), its next request wrote the whole context again: ≈$1.5K after 5–60 minute gaps, ≈$920 of it right after long-running Bash commands.
Main sessions left idle. Resuming main sessions after more than an hour cost ≈$1.3K, ≈$1.1K of it in sessions that sat idle at the prompt. And 30 of my 47 manual compactions happened after more than an hour idle, so I was paying to re-cache everything just to summarize it. A warm compaction of an 800K context costs about $0.50 on Opus 5.5; a cold one about $4.40. This is the part Claude Code 2.1.286 now handles, by compacting idle sessions over 200K tokens while they are still warm; 96% of that ≈$1.1K was above 200K. The subagent part above is still yours.
The 1-hour main-session cache shows up clearly. Requests with at least 30K of context, September 1 to October 12, same model as the previous request:
| Idle gap before the request | Main session: hit / rebuild | Subagents: hit / rebuild |
|---|---|---|
| under 5 min | 99.8% / 0.2% | 99.8% / 0.2% |
| 5–30 min | 97% / 3% | 19% / 81% |
| 30–55 min | 95% / 5% | 2% / 98% |
| 55–65 min | 57% / 43% | 11% / 89% |
| 65–120 min | 4% / 96% | 0% / 100% |
Every main-session cache write in that period used the 1-hour lifetime (189M tokens); subagent writes were 99.9% 5-minute (734M tokens). Gaps are measured between logged responses, so the buckets around 60 minutes are approximate.
Should subagents get a 1-hour cache?
Claude Code has a setting for it, subagentPromptCacheTtl (and experimental.cacheTtl per agent). It isn’t free: every token a subagent writes then costs 2× input instead of 1.25×, whether or not the agent ever sits idle. It pays off only when enough of an agent’s cache writes are rebuilds after 5–60 minute gaps. With r as that share:
1-hour cost = 2 × (1 − r) + 0.05 × r (those rebuilds become cache reads: 0.05× input on Opus and Sonnet 5.5)
5-minute cost = 1.25
break-even: r ≈ 38.5%
r is a share of the agent’s cache-write tokens. Only the writes that still happen pay 2×; the avoided ones become reads.
Since September 1, teammates were at 59%, so a 1-hour cache would pay off if you use agent teams. Plain subagents and forks were at 27%, so it wouldn’t. Moving all subagents to a 1-hour cache would have saved about 3% of total usage. Keeping contexts small and not waiting inside them did far more.
This is the number I’d expect to vary most between people, which is why I’m turning the audit into a tool you can run on your own transcripts (below).
What I changed
- Agent teams off. Named spawns are ordinary subagents again.
- Small, disposable, tiered agents. One task per agent, then a fresh one with a written brief: a read-only Haiku 5.5 scout (30 turns, compacts at 100K), a Sonnet 5.5 implementer (100 turns, 250K) and an Opus 5.5 reviewer (60 turns, 200K), each with its own effort level. I only message an agent again if it finished under 5 minutes ago and is still small.
- Nobody waits inside a big context. Long builds, test suites and poll loops run from the main session, which has the 1-hour cache, in the background. A 20-line wrapper writes the full log to a file and prints only the exit code and the failure lines; a fresh agent gets the failures and the log path.
- Compaction: a backstop and deliberate summaries. A 400K auto-compact backstop (
autoCompactWindow), a status line with context size and a cache countdown, and/compact <focus>at the end of each phase. I had also built a phone alert for idle sessions before noticing that Claude Code 2.1.286 already compacts them; I deleted it. - Less noise in the context. Bash output compacted with RTK, and the advisor tool off (it re-reads the whole conversation, uncached, on every call).
The rules for 2–4 live in my global CLAUDE.md, so the main agent follows them when it delegates. Generic versions of the agent files, the rules and the wrapper are in the tool’s examples/.
Results after one week
The 7 days after the changes (October 12–19), measured with the same tool and rules, next to the week before and the four months above:
| Share of usage, unless noted | Four months | Week before | Week after |
|---|---|---|---|
| Avoidable cache rebuilds | 26% | 27% | 5% |
| Subagents, teammates and forks | 57% | 70% | 34% |
| Contexts over 400K | 58% | 68% | 3% |
| Contexts under 200K | 16% | 10% | 56% |
| Agents whose context passed 500K (share of agents) | 17% | 37% | 0 |
| Cost per request at API prices | $0.13 | $0.11 | $0.06 |
- About as many requests, half the cost. The two weeks had nearly the same number of requests (31.6K before, 30.2K after), and the week after ran 2.7 times as many agents (456 against 171), none of them past 500K tokens. It came to ≈$1.8K at API prices, against ≈$3.5K the week before and ≈$5.9K for my most expensive 7 days.
- Not cheaper models, and not Claude Code’s idle compaction. The model mix got more expensive: Opus 5.5 and Fable 5.1 went from 79% to 88% of usage. Idle compaction ran 8 times, and the tool estimates it saved ≈$9, 0.5% of the week.
- More compactions, as intended. They went from 29 to 163 a week, and rewriting the compacted contexts cost 2.4% of usage.
- Less shell output. RTK filtered about 17,000 commands and cut their output by 74%, roughly 11M tokens that never entered a context.
- Fewer subagent rebuilds. Small agents rarely sit idle on a big context: 14% of their cache writes were rebuilds after 5–60 minute gaps, against 27% before, so a 1-hour subagent cache is even further from its 38.5% break-even.
One week is a small sample, the work differs from week to week, and Claude Code went from 2.1.293 to 2.1.300 during it.
Run it on your own transcripts
claude-cache-audit runs the same analyses on your transcripts:
uvx claude-cache-audit
pipx run claude-cache-audit works too; it needs Python 3.9 or later and nothing else. It reads the transcripts Claude Code keeps on your machine, makes no network calls, and never prints prompt text or file contents. It covers the last 30 days by default (--since 2026-09-01 or --all for more) and reports:
- the usage split, and the split by main session, subagents, teammates and forks;
- subagents by peak context;
- rebuilds by cause (idle gap, compaction, idle compaction, model switch, changed prefix), with cold starts apart;
- the cache hit rate by idle gap;
- per agent type, whether a 1-hour subagent cache would pay off for you.
claude-cache-audit rebuilds --top 20 lists the costliest rebuilds one by one, and --json gives everything as JSON.
claude-cache-audit --share prints the same findings as ratios only, safe to paste anywhere. Part of mine, for the four months above:
- Cost split: cache reads 53.0%, cache writes 40.1% (1h writes 16.9%), uncached input <0.1%, output 6.8%
- By agent kind: main 42.5%, subagent 12.8%, teammate 41.3%, fork 3.4%
- Rebuild premium: 25.9% of total cost (the post's rule: 26.5%)
- Subagent cost by peak context: <100K 1.0%, 100-250K 9.0%, 250-500K 26.1%, >=500K 63.9%
- 1-hour cache, teammate agents: expired-rebuild share of cache writes 58.5% vs break-even 38.6%, would pay off
Caveats
- One person’s usage, mostly heavy multi-agent work. Your split will differ, the rebuild shares most of all.
- API-equivalent dollars are a proxy for plan usage, not a bill.
- Claude Code changes quickly; this is as of 2.1.306 (October 2026). Idle compaction (2.1.286) arrived at the very end of my data window, so the four-month numbers come from before it.
Your numbers
If you run the audit, I’d like to see your split, especially the subagent share and the rebuilds by agent type. claude-cache-audit --share prints ratios only (no names, paths or dollar figures). Post it in the repo’s Share your audit numbers thread, and I’ll publish a roundup of what different setups look like.