Verified against 22 measured Claude Code 2.1.292 runs · Updated
What one Claude Code task cost on Opus, Sonnet, and a long context
We ran this because we wanted to know what actually made the same Claude Code task cost more: model choice, effort, or carrying a long conversation. To find out, we gave Claude Code 2.1.292 the same Next.js build task 22 times and priced the token usage at Anthropic's list rates. In the cache-controlled runs (Stage 1B), Sonnet 5.5 at high effort had a median task cost of $0.09, against $0.45 for Opus 5.5 at high effort. Running the same Opus task after about 205,000 tokens of cached context raised its median to $1.52.
These are API-equivalent dollars for one task, not measurements of Claude subscription quota.
- •Sonnet cost about 0.21× what Opus High did at the median, and every Sonnet run was cheaper than every Opus High run.
- •None of the 5 Sonnet builds started the app or tried a browser check. All 17 Opus builds did both.
- •All 22 builds passed our functional checks, but Opus and Sonnet handled a selected issue hidden by a search differently.
- •Preloading about 205,000 tokens of context made the Opus task about 3.4× as expensive. Unrelated Vim documentation cost about the same ($1.43).
- •Medium effort was cheaper at the median, but the runs overlapped too much to claim a saving.
The measured costs
Stage 1B is the cleaner of our two rounds. Every fresh run started with its system prompt and task already in cache, and the order of the 12 main runs was randomized. Stage 1A ran first, without that control, and is shown separately below.
| Stage 1B condition | Runs | Median | Range | vs Opus High | Requests |
|---|---|---|---|---|---|
| Sonnet 5.5 High, fresh | S5, S3, S4 | $0.0925 | $0.0916 to $0.1004 | 0.21× (0.17 to 0.29) | 4, 4, 5 |
| Opus 5.5 Medium, fresh | M4, M5, M3 | $0.3555 | $0.2168 to $0.3644 | 0.80× (0.40 to 1.07) | 6, 13, 17 |
| Opus 5.5 High, fresh | B3, B5, B4 | $0.4456 | $0.3411 to $0.5407 | 1.00× (0.63 to 1.58) | 17, 20, 12 |
| Opus 5.5 High + Next.js docs | L4, L3, L5 | $1.5157 | $0.7370 to $1.7187 | 3.40× (1.36 to 5.04) | 22, 26, 9 |
| Opus 5.5 High + Vim docs | C1, C2 | $1.4341 | $1.3945 to $1.4737 | 3.22× (2.58 to 4.32) | 21, 21 |
The bracketed range is the pessimistic one: the condition's cheapest run over Opus High's most expensive, and its most expensive over Opus High's cheapest. Run IDs are condition letter plus sequence number.
Stage 1A, reported separately
Stage 1A ran two of each condition with no cache warm-up. Three of its fresh runs (B1, M2, S2) started with part or all of the system prompt uncached, and S2, the first Sonnet process of the day, paid about $0.077 to write its whole 19,344-token prefix. That one write was 44% of S2's cost. The direction of every comparison matches Stage 1B.
| Stage 1A condition | Runs | Median | Range | vs Opus High |
|---|---|---|---|---|
| Sonnet 5.5 High, fresh | S2, S1 | $0.1345 | $0.0928 to $0.1762 | 0.31× |
| Opus 5.5 Medium, fresh | M2, M1 | $0.2734 | $0.2506 to $0.2962 | 0.62× |
| Opus 5.5 High, fresh | B1, B2 | $0.4406 | $0.3416 to $0.5396 | 1.00× |
| Opus 5.5 High + Next.js docs | L1, L2 | $1.2025 | $0.9117 to $1.4932 | 2.73× |
We don't publish a combined estimate across the two stages, because the pooling rule in our plan failed (details under How the study worked). A median of four or five runs is jumpy anyway: dropping B1 alone moves the Opus High median by 12%.
Why did Sonnet cost so much less than Opus?
Two reasons, and the second is bigger than the first. Sonnet's list prices are lower, and Sonnet did a lot less work on this task.
| Stage 1B | Opus 5.5 High | Sonnet 5.5 High |
|---|---|---|
| Output price, per million tokens | $20 | $10 |
| 1-hour cache write price | $8 | $4 |
| Cache read price | $0.20 | $0.20 |
| Model requests per run | 12, 17, 20 | 4, 4, 5 |
| Median output tokens | 10,979 | 5,218 |
| Median tool calls | 19 | 3 |
| Median cost per request | $0.027 | $0.023 |
| Median task cost | $0.4456 | $0.0925 |
Price alone gets you to roughly 0.6×. If you take the tokens from the median Opus run (B3) and bill them at Sonnet's rates, it comes to about $0.27, not $0.09. Turn it around and Sonnet's three Stage 1B runs, billed at Opus rates, would have cost $0.16 to $0.18, still well under the cheapest Opus High run at $0.34. The rest is volume. Sonnet read around 80,000 cache tokens per run where Opus read about 490,000.
What Opus did with the extra requests
We went through the tool calls in every run. All 17 Opus builds, in every condition and both stages, ran the typecheck and production build, started the app with next start, and tried to drive it in a headless browser with Playwright. Several spent requests just locating a browser binary in the container, and several made further edits after their browser checks. None of the 5 Sonnet builds did any of that runtime work. Each one read the project, wrote the component, and ran typecheck and build, usually chained onto the same shell command as the file write.
Did Opus and Sonnet build the same thing?
Not quite. All 22 builds passed all 22 core checks in our functional assessment, which covers selection, the live count, reassignment, Undo, search and the 390px layout. Where they differ is a selected issue that a search has hidden. The assessment recorded what each build did but didn't score it.
A selected issue hidden by a search
The prompt said a selection hidden by the search “should not silently reassign or lose track of it incorrectly.” To see what each build did, the assessment selected two issues, typed a search that hid one of them, and reassigned to Marcus T.
| What happened to the hidden issue | Opus builds | Sonnet builds |
|---|---|---|
| Reassigned it too | 17 of 17 | 1 of 5 (S5) |
| Left it unchanged, still selected | 0 of 17 | 2 of 5 (S2, S3) |
| Left it unchanged, deselected | 0 of 17 | 2 of 5 (S1, S4) |
Every build disclosed the hidden selection before you applied anything. This is the text the two median runs added to the page:
- 1 selected issue is hidden by the current search and will also be reassigned.
- Deselect hidden
- Showing 1 of 8 issues · 2 selected
- Reassigned 2 issues to Marcus T.
- Undo
- Dismiss
The hidden issue was reassigned along with the visible one.
- Showing 1 of 8 issues
- 1 selected (+1 hidden by search, not affected)
- Reassign 1 issue
- 0 selected
- Reassigned 1 issue to Marcus T..
- Undo
Only the visible issue changed. The hidden issue kept its assignee and was no longer selected.
Opus told you the hidden issue would be included and included it. Four of the five Sonnet builds told you it wouldn't be changed and didn't change it, which isn't silent reassignment. The weaker spot is S1 and S4. After applying, they also cleared the hidden issue's selection, so an issue you had picked ended up unchanged and unselected, with nothing on screen saying so after the fact. That's a small gap in an edge case, not a broken feature.


Why did a long context make the same task cost 3.4 times as much?
Each model request in the long-context runs had to reread roughly 205,000 cached tokens, which at Opus's cache-read price of $0.20 per million costs about $0.041 a request. The task made 9 to 26 requests, so the bill depends heavily on how many it needed.
To build that preloaded context, Claude Code first read 27 Next.js documentation files over three turns, producing a 205,328-token conversation, and the task prompt was sent as the next turn. The task turn read it from cache, as intended.
| Run | Output | Cache writes | Other cache reads | Preloaded reread | Total |
|---|---|---|---|---|---|
| B3 | $0.2196 | $0.1271 | $0.0987 | none | $0.4456 |
| L4 | $0.3313 | $0.2138 | $0.0671 | $0.9034 | $1.5157 |
Between the two median runs, L4 cost $1.07 more than B3, and about $0.90 of that is the preloaded context. The rest came from L4 doing more: 22 requests and 16,563 output tokens against B3's 17 requests and 10,979. The spread across the long-context runs follows request count: L5 finished in 9 requests for $0.74; L3 took 26 and cost $1.72.
Did it matter what the context said?
Not that we could see. The control condition repeated the long-context runs with one change: the preloaded context was about 209,000 tokens of Vim 9.1 help files, picked to avoid web-development vocabulary (the exact rule is in the dataset). Its median task cost was $1.43, about 0.95× the Next.js condition's $1.52. Both control runs made 21 requests, against 22 for the median Next.js run, and wrote a similar amount of output. No long-context run, with either kind of material, opened the preloaded files again during the task.
That points to the cost coming from carrying a long context, not from the documentation steering the model. Two control runs can't rule out smaller effects of content, though.
What it cost to build the context
The task costs above leave out the cost of building the context. From scratch it ran $1.65 to $1.67 on Opus, more than three median fresh tasks on its own. When the previous run had left an identical prefix in cache, it cost only $0.20. Whether that happened depended on the model's replies while building the context: C2 couldn't reuse C1's cache because its replies came out slightly different, which changed every later prefix.
| Run | Material | Context built | Build $ | Requests | Preloaded reread $ | Task $ | Build + task $ |
|---|---|---|---|---|---|---|---|
| L1 (1A) | Next.js docs | from scratch | $1.6673 | 12 | $0.4928 | $0.9117 | $2.5791 |
| L2 (1A) | Next.js docs | from cache | $0.1979 | 21 | $0.8624 | $1.4932 | $1.6911 |
| C1 (1B) | Vim docs | from scratch | $1.6734 | 21 | $0.8764 | $1.4737 | $3.1470 |
| C2 (1B) | Vim docs | from scratch | $1.6546 | 21 | $0.8761 | $1.3945 | $3.0490 |
| L4 (1B) | Next.js docs | from scratch | $1.6673 | 22 | $0.9034 | $1.5157 | $3.1831 |
| L3 (1B) | Next.js docs | from cache | $0.1979 | 26 | $1.0677 | $1.7187 | $1.9166 |
| L5 (1B) | Next.js docs | from cache | $0.1979 | 9 | $0.3696 | $0.7370 | $0.9349 |
Did medium effort save money?
Probably, but we can't say by how much. Opus 5.5 at medium effort had a lower median than high effort in both stages: $0.3555 against $0.4456 in Stage 1B, and $0.2734 against $0.4406 in Stage 1A. The runs overlapped, though. M3 cost $0.3644, more than B4's $0.3411, and the Stage 1B medium runs ranged from 6 to 17 requests.
Cost per request was the same at both effort levels, about $0.027. When medium was cheaper, it was because that run made fewer requests and wrote less, not because each request got cheaper.
Does this tell you how much of your Claude plan a task uses?
No. Every figure here is what the tokens would cost at Anthropic's published API prices. Anthropic doesn't publish how tokens map onto the five-hour and weekly meters, and we didn't observe those meters at all: every run was billed to promotional cloud session credits. So 0.21× and 3.4× are cost ratios for one task, not the share of your weekly limit you'd save or spend.
What carries over is the mechanism. More requests, more output and a bigger context all cost more, and Anthropic lists conversation length, multi-step tool work and model choice among the things that use up your allowance. If your meter drains fast in a long Claude Code session, measure your burn rate before and after starting a fresh one. If you pay for overflow with usage credits, which Anthropic bills at API rates, these dollar figures are a closer guide, before any usage-bundle discount. The Opus 5.5 and Sonnet 5.5 pages cover plan-level details.
How the study worked
The task
A small Next.js and TypeScript Issue Board with eight seeded issues, three assignees (Dana K., Marcus T. and Priya N.) and a title search. Each run had to add bulk reassignment: per-row selection, a live selected count, a reassign control fed from the seed data, a scoped Undo, search that keeps working on the updated data, a layout that fits 390px, semantic controls, and a passing typecheck and production build. Every run started from the same fixture commit in a freshly rebuilt workspace.
Read the exact task prompt
This repository contains a small internal Issue Board app (Next.js + TypeScript). It currently shows a static list of seeded issues with a client-side title search. Add a "Bulk assignee reassignment" feature to the existing board without breaking its current behavior: - Add a way to multi-select issues from the list (checkboxes or an equivalent explicit selection control on each row). Show a live count of how many issues are currently selected. - When at least one issue is selected, show a control to reassign all selected issues to a different assignee, chosen from the existing set of assignees already present in the seed data (do not hardcode a new assignee list separately from the data). - Applying the reassignment must update the assignee shown on every selected issue's row immediately, and then clear the selection. - Add an "Undo" action that appears right after a bulk reassignment completes and, if used, reverts every issue that reassignment just touched back to its previous assignee. Undo must only affect that specific reassignment, not the whole board's history. - The existing title search must keep working after a bulk reassignment: filtering must apply to the current (post-reassignment) data, and selection state for any issue that becomes hidden by the search should not silently reassign or lose track of it incorrectly. - Preserve every issue's existing fields (id, title, priority, status, updatedAt) exactly as before; only the assignee field changes as a result of this feature. - Keep the app usable on both desktop and mobile widths. On a 390px-wide viewport, the new selection and reassignment controls must fit without horizontal scroll. - All interactive controls must be real semantic HTML (checkboxes, buttons, select/labeled inputs), not divs acting as controls. - Production build must succeed. TypeScript must typecheck. No material browser console errors. No new external dependencies. Do not ask questions. Make reasonable product and interaction decisions yourself. Use the existing Next.js and TypeScript setup and the existing component/data organization in app/board/.
Conditions and runs
| Code | Model | Effort | Preloaded context | 1A | 1B |
|---|---|---|---|---|---|
| B | Opus 5.5 | high | none (fresh session) | 2 | 3 |
| M | Opus 5.5 | medium | none (fresh session) | 2 | 3 |
| S | Sonnet 5.5 | high | none (fresh session) | 2 | 3 |
| L | Opus 5.5 | high | ~205k tokens of Next.js docs | 2 | 3 |
| C | Opus 5.5 | high | ~209k tokens of Vim docs | 0 | 2 |
All runs used Claude Code 2.1.292 in an Anthropic-hosted cloud container, one headless process per run, strictly one at a time, on October 7, 2026 (UTC). Auto-memory, built-in plugins, MCP servers, slash commands, web search and web fetch were off. No run used subagents, made side-model requests or hit compaction, and every run used the requested model.
Stage 1B ran the two control runs first, then three more of each main condition in randomized order. Before every fresh run we started a one-request warm-up with identical arguments, so the measured run read its system prompt and task from cache. Warm-ups cost $0.165 in total and aren't counted in task cost.
How cost was calculated
We took the change in Claude Code's per-model usage totals across the task turn (uncached input, output, cache reads, and 5-minute and 1-hour cache writes) and multiplied each by Anthropic's list price for that model, retrieved on October 7, 2026. Opus 5.5 is $4 input, $20 output, $0.20 cache read and $8 for a 1-hour cache write per million tokens; Sonnet 5.5 is $2, $10, $0.20 and $4. Every cache write we observed used the 1-hour lifetime, so writes are priced at that rate.
We used the streamed per-request usage to count requests and study cache behavior, but not to price them, because streamed output-token counts can be provisional. As a check, we compared each total with the change in Claude Code's own cumulative cost ledger over the same turn, and every task, context-building and warm-up turn in all 22 runs matched exactly. In all, Stage 1B cost $14.94 at list price, of which $5.39 was building long contexts.
How the builds were checked
Every build got two graders. The original one, written along with the task, has 15 core checks and failed five builds (B1, B2, S1 and S2 in Stage 1A, M3 in Stage 1B) on a single check that looked for the word “reassign” in button and select text. Those builds put “Reassign to” (or “Reassign 2 issues to”) in a <label> and committed with a button reading “Apply”, “Apply to 2” or “Apply to 2 shown”. The same grader's own reassignment check passed on all five, so the feature worked and the wording check was brittle. The run table at the bottom shows the original results as they came out.
The revised functional assessment (22 core checks, 6 secondary) finds controls by what they do rather than what they say. We wrote it after inspecting the Stage 1A builds and froze it before Stage 1B started, so it isn't an independent evaluation. It checks install, build and typecheck, per-row selection and its live count, a reassign control limited to the seeded assignees, exact assignee changes, a scoped Undo across two batches, search over the updated data, and no overflow at 390px with the bulk controls showing. It also fails console errors and a hardcoded assignee list. It records hidden-selection behavior without scoring it, and it doesn't look at code quality or accessibility beyond semantic controls. Before using it we confirmed it caught defects we injected into synthetic boards, including history-wide undo, stale search and overflow at 390px.
When the plan was fixed
Both stages had a plan written before the first run and committed shortly after it began, so this was a written plan rather than a strict preregistration. The Stage 1B plan fixed the run order, cache policy, control material, and the rules for pooling and adding runs. It said to pool the stages only if dropping the three not-fully-cached Stage 1A runs moved no median ratio by more than 10%. It moved Opus Medium by 19.7%, Sonnet by 11.9% and the long-context condition by 11.7%, so the stages stay apart. The three extra long-context runs in Stage 1B (L3, L4, L5) were added under the plan's rule, after the control runs met its conditions. Exact timestamps are in the dataset.
All 22 runs
In execution order. Task cost excludes the cost of building the long contexts and the warm-ups. The full records, with cost by category and the captured UI text, are in the JSON dataset.
| Run | Condition | Task $ | Build $ | Req. | Output tok. | Cache read tok. | Prompt cached on first request | Original | Revised | Hidden selected issue | Browser check |
|---|---|---|---|---|---|---|---|---|---|---|---|
| M2 1A | Opus 5.5 Medium, fresh | $0.2506 | 6 | 6,447 | 138,858 | nearly all | pass 15/15 | pass 22/22 | Reassigned it too | yes | |
| B1 1A | Opus 5.5 High, fresh | $0.5396 | 21 | 12,393 | 637,828 | nearly all | fail 14/15 | pass 22/22 | Reassigned it too | yes | |
| B2 1A | Opus 5.5 High, fresh | $0.3416 | 8 | 10,031 | 199,754 | all | fail 14/15 | pass 22/22 | Reassigned it too | yes | |
| S2 1A | Sonnet 5.5 High, fresh | $0.1762 | 4 | 5,606 | 61,246 | none | fail 14/15 | pass 22/22 | Left it unchanged, still selected | no | |
| L1 1A | Opus 5.5 High + Next.js docs | $0.9117 | $1.6673 | 12 | 12,834 | 2,582,075 | nearly all | pass 15/15 | pass 22/22 | Reassigned it too | yes |
| S1 1A | Sonnet 5.5 High, fresh | $0.0928 | 4 | 4,962 | 80,436 | all | fail 14/15 | pass 22/22 | Left it unchanged, deselected | no | |
| L2 1A | Opus 5.5 High + Next.js docs | $1.4932 | $0.1979 | 21 | 17,893 | 4,654,715 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes |
| M1 1A | Opus 5.5 Medium, fresh | $0.2962 | 11 | 7,662 | 288,942 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes | |
| C1 1B | Opus 5.5 High + Vim docs | $1.4737 | $1.6734 | 21 | 16,467 | 4,686,403 | nearly all | pass 15/15 | pass 22/22 | Reassigned it too | yes |
| C2 1B | Opus 5.5 High + Vim docs | $1.3945 | $1.6546 | 21 | 14,657 | 4,637,623 | nearly all | pass 15/15 | pass 22/22 | Reassigned it too | yes |
| B3 1B | Opus 5.5 High, fresh | $0.4456 | 17 | 10,979 | 493,711 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes | |
| M4 1B | Opus 5.5 Medium, fresh | $0.2168 | 6 | 6,054 | 141,341 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes | |
| S5 1B | Sonnet 5.5 High, fresh | $0.1004 | 4 | 5,455 | 80,570 | all | pass 15/15 | pass 22/22 | Reassigned it too | no | |
| L4 1B | Opus 5.5 High + Next.js docs | $1.5157 | $1.6673 | 22 | 16,563 | 4,852,727 | nearly all | pass 15/15 | pass 22/22 | Reassigned it too | yes |
| B5 1B | Opus 5.5 High, fresh | $0.5407 | 20 | 13,940 | 617,418 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes | |
| B4 1B | Opus 5.5 High, fresh | $0.3411 | 12 | 9,494 | 337,332 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes | |
| M5 1B | Opus 5.5 Medium, fresh | $0.3555 | 13 | 8,977 | 350,807 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes | |
| L3 1B | Opus 5.5 High + Next.js docs | $1.7187 | $0.1979 | 26 | 18,312 | 5,751,337 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes |
| S3 1B | Sonnet 5.5 High, fresh | $0.0916 | 4 | 4,866 | 80,556 | all | pass 15/15 | pass 22/22 | Left it unchanged, still selected | no | |
| M3 1B | Opus 5.5 Medium, fresh | $0.3644 | 17 | 8,326 | 470,536 | all | fail 14/15 | pass 22/22 | Reassigned it too | yes | |
| S4 1B | Sonnet 5.5 High, fresh | $0.0925 | 5 | 5,218 | 109,569 | all | pass 15/15 | pass 22/22 | Left it unchanged, deselected | no | |
| L5 1B | Opus 5.5 High + Next.js docs | $0.7370 | $0.1979 | 9 | 11,739 | 1,914,479 | all | pass 15/15 | pass 22/22 | Reassigned it too | yes |
Limitations
- One task, one fixture, one Claude Code version, one cloud environment, one morning. Other tasks, especially longer or harder ones, may rank differently.
- Small samples: two or three runs per condition per stage and two control runs. Opus varied more from run to run than some of the effects we were measuring.
- Passing the functional assessment says the feature works. It isn't evidence that the builds are equal in quality.
- The long context was built by reading documentation files, not grown over a real coding session. Tool output or code in context might behave differently.
- The warm-up used a hidden CLI option (
--max-turns 1). We confirmed it worked by matching context size and full cache reads, not from documentation.
Data and citation
All 22 run records with cost by category, token counts, requests, cache measurements, context-building costs, both graders' results and the hidden-selection observation, plus the task prompt, prices, conditions and limitations.
The dataset is a sanitized extract. It doesn't include raw Claude Code transcripts, streamed event logs, the source diffs or code each build produced, the grader harness, or any account, session or environment identifiers. The experiment repository itself is private, so the per-run figures here can't be independently re-derived from raw logs yet.
If you quote a ratio, please quote the task, the stage and the fact that it's API-equivalent cost. Other first-party studies are on the research page.