One run that checked documentation against code launched 85 agents and would have cost about $26 at API prices. All 85 ran on the most expensive model, and nobody had picked it: the script named no model, so the agents inherited the session's. I went through the logs of that run and three others to see how to reduce Claude Code token usage in workflows. The model's replies cost almost nothing. The money goes to every agent re-reading its own context, over and over.
This is the second article about workflows. What the mode is, how to start it and what limits it has, I covered in the first article on Claude Code workflows. Here: only numbers, and what I changed in my scripts after measuring.
The short version:
- Model replies are about 2% of a run's cost. Between 65% and 84% goes to writing context into the cache.
- The most expensive stage is re-checking findings: 50% to 78% of a run.
- The model nobody chose turned out to be the biggest line item. After I assigned a model to each role, reviewing one commit dropped from $3.20 to $1.23.
- Re-running with no new commits now costs under a cent: one small agent compares state and exits.
- Savings can't be measured honestly without a reference task set. I don't have one yet, and that is the main open item.
How I measured Claude Code token cost#
Every workflow agent has a log: ~/.claude/projects/<project>/<session>/subagents/workflows/wf_*/agent-*.jsonl. Each model response entry has a message.usage field: input tokens, cache reads, cache writes, output. I summed them by stage and multiplied by the API pricing as of November 6, 2026:
| Model | Input | Cache write, 5 min | Cache read | Output |
|---|---|---|---|---|
| Opus 5.5 | $4 | $5 | $0.20 | $20 |
| Sonnet 5.5 | $2 | $2.50 | $0.10 | $10 |
| Haiku 5.5, prompt up to 100K | $0.10 | $0.125 | $0.01 | $0.50 |
Prices are per million tokens. On a subscription a run doesn't charge money, but the same tokens eat into plan limits, so the proportions hold.
One caveat. The logs show suspiciously few output tokens, 30 to 100 per request, so the model's reasoning seems to be missing from them. The output share is therefore a lower bound. The conclusion survives it: even at ten times the output, it stays under 20% of the cost.
Where Claude Code token usage goes#
Four runs on one branch, every agent on Opus 5.5:
| Run | Agents | Requests | ≈ $ | Re-check share |
|---|---|---|---|---|
| Review of the whole branch, 60 files | 58 | 379 | 14.2 | 66% |
| Review of one commit, 4 files | 10 | 57 | 3.2 | 50% |
| Docs-vs-code check and page fixes | 85 | 349 | 26.1 | 78% |
| Build and tests until green | 1 | — | ≈ 0.1 | — |
The mechanics are simple. An agent starts with about 50K tokens of context: system prompt, tools, CLAUDE.md, memory, the task. CLAUDE.md and memory alone take 11K to 13K tokens before the first line of the task. Then the agent makes 5 to 8 requests, and each request carries the whole accumulated context along with tool results. Roughly: agents × requests per agent × context size × model price. All four factors can be reduced.
The cache doesn't always help. On Opus 5.5 a cache read costs $0.20 and a write costs $5, 25 times more. In the reviews, the checkers read a shared prefix from a neighbor's cache: the median write on the first request was zero. In the docs check, each of the 76 checkers wrote its own prefix from scratch, 32K tokens apiece. That is about $12 of the $26 spent on putting the same text into the cache 76 times.
I never found out why the cache wasn't shared there. According to the workflow docs, agents read each other's cache only when model, effort level, agent type, tools, response schema and working directory all match. A workflow agent's cache lives for five minutes, even on a subscription.
Re-checking findings: expensive and often wasted#
The "one agent finds, another tries to refute" pattern is the best thing in workflows. It is also what eats the most. Every finding gets its own checker with its own context.
In the docs check, the checkers refuted 36 of 76 discrepancies, 47%. Almost half of the stage's money went to filtering out discrepancies that didn't exist. The cost of one confirmed finding came out the same in every run, $0.9 to $1.2.
That leads to a conclusion that looks odd at first: it is cheaper to make the search stricter than to keep more checkers. If the finder has to bring a verbatim quote from the page and the line of code it read, fewer phantom discrepancies appear before the check even starts.
Outside work says the same. In the Refute-or-Promote preprint, ten reviewers unanimously confirmed an OpenSSL vulnerability that did not exist, and a single empirical test killed it. There is no controlled comparison there, just one case. But the lesson is clear: ten agreeing agents are not a fact. In CodeX-Verify each additional checker added less than the one before: +14.9, then +13.5 and +11.2 percentage points of accuracy.
How I reduce Claude Code token usage in my scripts#
Five changes, each aimed at one of the factors.
An explicit model for every agent. Per the docs, an agent with no model set runs on the session's model. Now every script starts with a table that can be overridden at launch:
const M = {
scope: 'haiku',
find: A.thorough ? 'opus' : 'sonnet',
verify: A.thorough ? 'opus' : 'sonnet',
state: 'haiku',
...(A.models || {}),
}Haiku 5.5 writes cache at $0.125 against $5 for Opus, 40 times cheaper. It gets scouting (which files changed) and saving state. Search and verification run on Sonnet. Opus stays for the release run and for one exception: in the third-party code audit I kept it on reading install scripts, because a missed malicious hook costs more than any amount of tokens. Mechanical steps and checks of minor findings got effort: 'low'.
Duplicates are merged before checking. Three reviewers often find the same bug from different sides. If the file is the same and the lines differ by no more than three, the finding is checked once. Minor findings over the limit are not checked; they go to a separate list and into the log, so the cut is never silent.
The checker must bring a fact. A call site, a condition higher up the stack, command output, a verbatim quote. No fact, finding rejected:
`Keep a finding only with evidence — what you found and where ` +
`(file:line or command output). No evidence → reject.`Three votes remain only for serious findings in the release run.
Check only what's new. The review saves the last reviewed commit to a file inside .git (git rev-parse --git-path change-review-state.json), so it never lands in a commit. The next launch looks at lastReviewedSha..HEAD and carries over open findings for untouched files. A full run happens before a pull request, after a rebase and after prompt changes; the script has a prompt version number for that. Incremental review works the same way at CodeRabbit, and CI picks affected tests the same way.
I did not retire the full run, and there is a reason. The most serious bug of the day came from it: it tied a client, a service and settings together across three files. An incremental pass over a single file would not have seen it.
Early exit. If nothing has changed since the last run, the script returns right after scouting and starts no reviewers.
The result on the same repository:
| Run | Agents | Requests | Models | ≈ $ |
|---|---|---|---|---|
| Commit review, old script | 10 | 57 | Opus | 3.20 |
| Commit review, new script | 10 | 40 | Haiku + Sonnet | 1.23 |
| Same, re-run with no new commits | 1 | 2 | Haiku | < 0.01 |
The quality comparison is loose. The old script looked at the commit before the review fixes and the new one after, so their findings differ: three confirmed against two. The price is comparable because the volume is the same: 4 to 6 files, 10 agents.
One more change has nothing to do with money; it is about the check-then-fix loop. In my translation script, the fix agent made its edits last and nobody read them again. Now a short re-check on Sonnet with effort: 'low' follows the fix. A loop should end on a check, or the last changes go into the commit unread.
What I haven't verified yet#
- There is no reference set. It needs 30 to 50 past pull requests with known bugs and a few deliberately planted ones. Without it I can't say how many subtle findings Sonnet misses compared to Opus.
- Why the cache wasn't shared in the docs check is unclear. That is up to $12 per run.
- 11K–13K tokens of shared rules still load into every agent: a 21 KB
CLAUDE.mdplus memory. The cost docs advise keepingCLAUDE.mdunder 200 lines and moving special-case rules into skills, which load on demand. I haven't done that yet. - All savings estimates except the review measurement are calculations, not measurements.
A separate note on the docs check. Its main problem is verifying every page in full on every run. The next step is to check only the pages tied to changed files. How to tie a page to code so that it knows by itself when it has gone stale, I described in the article on documentation anchors in code.
If you already have saved workflows, start with one command: grep -n "agent(" ~/.claude/workflows/*.js. Every call in its output that has no model in the options most likely runs on your session's model.



