The third step cost less than the first, in the session that was never cleared
The advice to clear between tasks is scoped to unrelated work, and on unrelated work it is not in question here. Applied to three related steps, which is what "one session per task" turns into in practice, the resumed session got cheaper as it went: its third step cost 25,312 tokens less than its own first step, in 10 runs out of 10. Clearing between the same steps cost more, also 10 out of 10.
Claude Code’s own cost documentation is specific about this. Under “Manage context proactively”: “Clear between tasks: Use /clear to start fresh when switching to unrelated work. Stale context wastes tokens on every subsequent message.” Elsewhere on the same page, unexpectedly high spend “usually traces back to long sessions that were never cleared”, and “clearing between unrelated tasks” is named as one of the two highest-impact habits.
Read the qualifier, because it is doing real work: unrelated. That advice is not what is measured here and this post does not refute it. What gets measured is what the advice turns into once the qualifier falls off, which it does constantly in the repeated form “one session per task, don’t let sessions get long”. Applied to steps that are related, the mechanism it describes runs backwards.
Three requirements, each building on the last: parse a duration string, format one, then a round-trip check that calls both. Three arms, identical requirement text, ten rounds each.
| Medians, 10 rounds per arm | Tokens | Dollars | Turns | Tool calls | Wall |
|---|---|---|---|---|---|
| One prompt, all three at once | 103,828 | $0.1697 | 4.5 | 3.5 | 25.4s |
| One session, three prompts | 274,436 | $0.3753 | 11.5 | 8.5 | 50.3s |
| Fresh session every step | 344,408 | $0.4361 | 15 | 12 | 61.6s |
All 30 runs behind this table passed the hidden test suite, so nothing here is a quality trade. Every figure in this post is the 2.1.228 measurement; the 12 re-verification runs added later are labelled by version in the corpus and are never pooled into these numbers.
The session got cheaper as it got longer
This is the part that inverts the stated reason. “Stale context wastes tokens on every subsequent message” predicts that later prompts in one session cost more than earlier ones, because they carry everything before them.
The third one cost less. Comparing each run against itself, so that nothing about how runs differ can leak in:
| Within one run | One session | Fresh session |
|---|---|---|
| Step 3 against step 1 | −25,312, cheaper in 10 of 10 | +1,276, cheaper in 4 of 10 |
| Step 2 against step 1 | −5,244, cheaper in 5 of 10 | +25,136, cheaper in 0 of 10 |
The resumed session’s third step is cheaper than its own first step in every single run, a sign test p of 0.0010. The fresh session’s third step is indistinguishable from its first, which is exactly what starting over should look like.
The decline is not monotone, and the middle row is why: step 2 goes either way, 5 of 10. So the honest shape is that the resumed session ends cheaper than it started, not that every step is cheaper than the one before it.
The action record says where the saving comes from. By step 3 the resumed session had stopped re-reading the file entirely, 0 of 10 runs, and went straight to Edit. The fresh session re-read it in 10 of 10, because it had no idea what was in it. At step 2, where the resumed arm’s result is a coin flip, it re-read in 5 of 10.
What the advice calls stale context is, on related work, the model already knowing what it built ten seconds ago. Carrying that history is cheaper than re-deriving it, and the saving grows as there is more to re-derive.
Clearing cost more, unanimously, but by less than it looks
Fresh sessions cost more than resumed ones in 10 of 10 paired rounds on tokens, turns, tool calls and wall clock, sign test p = 0.0010 on each. On dollars it is 8 of 10, p = 0.0547, which does not clear the usual bar, so the dollar direction is suggestive rather than established.
Per step, paired, the difference appears exactly where the design says it should and not before:
| Paired by round | Fresh dearer | p |
|---|---|---|
| Step 1, identical treatment in both arms | 7 of 10 | 0.1719 |
| Step 2 | 9 of 10 | 0.0107 |
| Step 3 | 9 of 10 | 0.0107 |
Step 1 is the same thing in both arms, a cold session running the same prompt, and it shows no significant difference. That null is the control on the design: the arms are equivalent until the treatment starts.
Being exact about the size: on totals the arms overlap. The cheapest fresh run, 297,798 tokens, is cheaper than the most expensive resumed run, 314,404. Round-to-round spread is larger than the gap between the arms, which is precisely why the comparison is paired. The honest form is “clearing was worse in every paired round by a modest amount”, not “clearing is 25% worse”.
The lever nobody mentions is bigger than the one everybody does
Both multi-prompt arms lose to simply asking for all three things at once, and that comparison is not close. One prompt is separated from both other arms: its worst run beats the best run of either arm on tokens, dollars, turns, tool calls and wall clock. Worst one-prompt run 115,501 tokens against a best-of-arm 235,135 and 297,798.
| Against one prompt | Tokens | Dollars | Turns | Tool calls |
|---|---|---|---|---|
| One session, three prompts | 2.64x | 2.21x | 2.56x | 2.43x |
| Fresh session every step | 3.32x | 2.57x | 3.33x | 3.43x |
So the advice points at a real effect and at the smaller one. Clearing versus not clearing moved tokens by 1.25x. Asking once versus asking three times moved them by 2.64x, and the answer came out the same.
What actually predicts the bill is turns
Fit a straight line through the 30 runs behind the table above, tokens against turn count, and it comes out at:
tokens = 2,025 + 23,116 per turn, with an R² of 0.9972.
The intercept’s 95% interval is −3,176 to 7,226, so it includes zero: there is no measurable fixed cost per run in this corpus beyond what the turns account for. The slope’s interval is 22,653 to 23,578. That one line predicts every arm’s mean to within 2.6%, including arms it is not fitted separately to: 106,046 predicted against 103,840 measured for one prompt, 267,856 against 274,984 for one session, 348,761 against 343,837 for fresh sessions.
This is why the three findings above are one finding. Splitting a task into three prompts adds turns. Clearing between them adds a few more, because the model re-reads what it already had. An unlucky speculative Bash at the start adds exactly one. Everything in this corpus is the same 23,000 tokens per turn, and the only question is how many turns your working habit buys.
The practical form: count the round trips, not the sessions. A habit that saves a session but costs a turn is a bad trade, and clearing between related steps is exactly that trade.
One extra turn, and the whole spread in this corpus
Every first call in the corpus landed in one of two groups with nothing between them: cheap or about 22,800 tokens more expensive. It looks like a hidden execution mode. It is not, and the tool record gives the cause with no ambiguity at all.
The first tool of the first call predicts the group in 30 runs out of 30. Every expensive first call opens with a speculative Bash before it looks at anything, then reads; every cheap one goes straight to Read. That is 5 turns against 4, 17 runs against 13, zero mixing.
And the size is exactly what one extra turn should cost. The gap is 22,791 tokens in the single-prompt arm, 22,729 in the resumed arm and 22,943 in the fresh arm, against a rate fitted across all 30 runs of 23,116 tokens per turn. So the largest source of variance in this corpus is the model occasionally running one exploratory command first, billed at the ordinary per-turn rate.
That is the same law the rest of the post is about, at a smaller scale. Cost tracks turns. One extra speculative command costs about 23,000 tokens; two extra prompts cost about 170,000.
It also changes how to read the table above. Group means per arm:
| First call | Cheap | Expensive |
|---|---|---|
| One prompt | 92,445 (n=5) | 115,236 (n=5) |
| One session | 90,386 (n=5) | 113,115 (n=5) |
| Fresh session | 90,358 (n=3) | 113,301 (n=7) |
The single-prompt arm sits about 2,000 tokens above the other two in both groups, because its one prompt carries all three requirement strings at once. Its pooled median of 103,828 is therefore a value no run actually took, sitting between the two groups.
Recomputing the headline ratios inside each first-call group, which removes part of this effect but not all of it, since every call draws its own turn count and only the first is being held fixed:
| Ratio to one prompt | Cheap first call | Expensive first call | Pooled |
|---|---|---|---|
| One session, tokens | 2.84x | 2.49x | 2.64x |
| Fresh session, tokens | 3.72x (n=3) | 2.99x (n=7) | 3.32x |
The residual is real and worth stating. Conditioning on the first call cuts the resumed arm’s spread from 79,269 tokens to about 54,000, and the fresh arm’s from 69,536 to about 47,000, and no further: the fresh arm is three independent cold sessions, so its later calls are still free to land anywhere. Inside the cheap first-call group its third call still ranges from 68,584 to 115,598.
Direction and rough size survive in both groups, and the separation claim never used medians at all. But 3.72x is the thinnest cell in the table, three runs, so quote the range rather than the pooled median if you are reusing these numbers.
A two-mode fan-out measured here earlier also partitioned perfectly on num_turns, and it is worth being clear that this is not the same phenomenon. There the split ran the other way and had no explanation: one-turn runs cost 53% more than nine-turn runs, which is why it was worth publishing. This split is the mundane kind, more turns costing more, with the extra turn visible in the record.
What this does not settle
It does not test the documented advice. That advice is about unrelated work, where a fresh session throws away context with no future value, and none of the mechanism measured here would apply. Nothing in this corpus argues against clearing when you genuinely change subject. What it argues against is the unscoped habit, which is a different claim that happens to be far more widely repeated.
One task shape, and a small one. Three steps on one file, about 45 to 56 lines of output. The resumed session’s advantage comes from remembering a file it just wrote, so the result should grow with how much later steps depend on earlier ones, and shrink toward nothing as the steps become independent. Where it crosses zero is untested, and that crossing point is the genuinely useful number this does not have.
Nothing here touches the context window. Ten prompts into a real working session the history is much larger, and at some point compaction or a cache miss changes the arithmetic. This measures three steps, not a working day. The cheapest arm is also the one that never got near a limit.
The dollar comparison between the two multi-call arms is the weakest number in the post, 8 of 10 rather than 10 of 10. Tokens, turns and tool calls are unanimous; dollars are not.
Re-verified on 2.1.229, the morning after
Claude Code moved from 2.1.228 to 2.1.229 hours after this went up, and every figure here is pinned to a version. Four fresh rounds per arm were run on the new build with the identical harness, asserting the same hidden-suite sha256 and the same three-way fixture verdicts before the runs were merged. They are appended to the corpus rather than replacing anything, and each run carries its claude_code_version.
Every claim held.
| On 2.1.229, 4 rounds per arm | Result |
|---|---|
| One prompt separated from both arms | still true on all four measures |
| Fresh dearer than resumed, paired | 4 of 4 |
| Resumed step 3 cheaper than its own step 1 | 4 of 4 |
| Fresh step 3 cheaper than its own step 1 | 1 of 4 |
| Tokens per turn | 23,274, against 23,116 on 2.1.228 |
The per-turn rate moved by 0.69%, and the 2.1.228 fit predicts each 2.1.229 arm mean to within 3.7%. The single-prompt median is flat at 103,598 against 103,828. The two multi-prompt medians rose a few percent, 5.8% and 3.1%, and their turn counts rose with them, 11.5 to 12 and 15 to 15.5, which is what the turn model predicts rather than a change in the effect.
Four rounds is a re-check, not a re-run: the paired direction is 4 of 4 but a sign test on four pairs cannot clear 0.05 whatever happens, so read it as consistent rather than as independent confirmation at strength.
Controls
The treatment was proven to have arrived, per run, not assumed. Every call reports the session id it ran in. The resumed arm required all three calls to report the same id and the fresh arm required three distinct ids, and every run in the corpus passes that check. Without it, --resume silently failing would look exactly like a null result.
The fixture discriminates three ways, control-tested before any model call. The empty module fails, a plausible minutes-only implementation fails, and a reference implementation passes. The suite is written from a constant after the model calls finish, so the model never sees it and cannot edit it; its sha256 is published.
The requirement text is byte-identical across arms. The one-prompt arm concatenates the same three strings the other arms send one at a time, so the arms differ in how the work is delivered, not in what was asked.
Bash was granted on every call in every arm and 97 of 98 calls used it across both versions, 69 of 70 in the 2.1.228 measurement. The exception is a model choice rather than a denial: it used Read and Edit, replied DONE, and its run passed. No reply in the corpus contains denial wording. That run is kept and scored, which is the conservative direction, because it is the cheapest fresh-session run in the corpus and dropping it would flatter the argument.
Isolation on every call, --setting-sources project, asserted onto the command line. Tokens from modelUsage, not .usage. The 2.1.228 measurement is two batches run separately, and the 2.1.229 re-check is a third; all three are published with their batch label and their version, so any of them can be separated out again.
Every run, with its full tool-call record and per-call session id, is published in session-vs-fresh.json.