Hacker News

Claude Code sends 33k tokens before reading the prompt; OpenCode sends 7k

Comments

Claude Code Is Way More Token-Hungry Than OpenCode. We Measured Exactly How Much

We put Claude Code and OpenCode on the same model, the same machine, and the same tasks, then examined everything sent and received.

Claude Code is far hungrier: When we asked both harnesses for a one-line reply, Claude Code used roughly 33,000 tokens of system prompt, tool schemas, and injected scaffolding before the prompt even arrived. OpenCode used about 7,000.

Claude Code is far more cache inefficient: OpenCode's request prefix was byte-identical in every run we captured; it paid to cache its payload once per session and read it back for pennies. Claude Code on the other hand re-wrote tens of thousands of prompt-cache tokens mid-session, run after run, and on the same task wrote up to 54x more cache tokens than OpenCode. Cache writes of course are billed at a premium, which accounted for the usage dashboard climbing when using Claude Code.

Config further bloats the prompt: A production repository's 72KB instruction (AGENTS.md or CLAUDE.md) file adds another (avg) 20,000 tokens to every single request. Five modest MCP servers add 5,000 to 7,000 more. By the time a real working setup sends its first request, it is 75,000 to 85,000 tokens deep before the user has typed a word.

Subagents add to the cost: A small task that cost 121,000 tokens done directly cost 513,000 tokens when fanned out to two subagents, because every subagent has its own bootstrap cost, and the parent then consumes its transcript.

We found one result in favour of Claude Code: On a multi-step task Claude Code's whole-task total came out lower than OpenCode's, because it batches tool calls into fewer requests while OpenCode re-pays its smaller baseline turn after turn. The meter starts higher; how the session unfolds decides who spends more.

The rest of this post shows how we measured all of this at the API boundary, where the tokens go, and what prompt caching does and does not save you.

Why measure this at all

Token overhead is cost, latency, and context budget. Every token of harness payload is a token of working context you cannot spend on code, and the baseline is re-sent, or re-read from cache, on every single turn. If you operate agentic AI in production, particularly under the EU AI Act where Article 12 expects you to log and understand your system's behaviour, "what does my agent actually send" is a question you should be able to answer with data rather than folklore.

Method

We spliced a logging proxy between each harness and the model endpoint.

harness (Claude Code / OpenCode) โ†’ logging proxy (captures request payloads + response usage) โ†’ model endpoint

The proxy records two things per request. The first is the exact JSON payload the harness emitted, meaning the system blocks, tool schemas, and messages. The second is the usage block the API returned, covering input tokens, cache writes, cache reads, and output tokens. The payload capture is ground truth for what the harness sends. The usage block is ground truth for what was metered.

We tested under these conditions.

  • Harnesses. Claude Code 2.1.207 and OpenCode 1.17.18, both pinned to claude-sonnet-4-5, July 2026.
  • Baseline isolation. Fresh config directories with no MCP servers, no user settings, and no memory; an empty workspace with no instruction files; permissions bypassed. Multiplier lanes then add one variable at a time.
  • Tasks. T1 says "Reply with exactly: OK" and isolates fixed overhead (three runs per harness). T2 reads a seeded file and summarises it. T3 is a write-run-test-fix loop against FizzBuzz plus a checker script.
  • Zero-tools variant. Claude Code with --tools "" and OpenCode with "tools": {"*": false}, separating system prompt from tool schema weight.

One honesty note before the numbers. Our traffic passes through a local LLM gateway that wraps requests in its own envelope, a constant we measured at roughly 6,200 tokens with bare calibration requests and subtracted from every metered figure below. Payload-level figures come from the captured request bodies, which the gateway cannot affect, and are exact. Character-to-token conversion for component estimates uses each harness's own measured ratio of 4.1 to 4.4 characters per token, derived from cold-cache anchors where the metered write equals the full payload, rather than a generic heuristic.

Part I. The floor

The fixed overhead of saying OK

The task was 22 characters. Here is what each harness sent with it on its first request.

Component Claude Code OpenCode
System prompt 27,344 chars, 3 blocks 9,324 chars, 1 block
Tool schemas 27 tools, 99,778 chars 10 tools, 20,856 chars
First-message scaffolding 7,997 chars of none
The actual prompt 22 chars 22 chars
First-turn payload (calibrated) ~32,800 tokens ~6,900 tokens

OpenCode's request is close to minimal. There is one system block that opens with "You are OpenCode, the best coding agent on the planet", ten classic coding tools, and your prompt as the only user content.

Claude Code's request is a platform bootstrap. The 27 tools include the coding core plus an entire background-agent and orchestration suite, from CronCreate and Monitor to the Task family, worktree management, and push notifications. Before your prompt, its first user message carries three injected reminder blocks: a catalogue of agent types for delegation, a catalogue of available skills, and user context.

Tool schemas are the dominant term for both. Roughly 24,000 of Claude Code's ~33,000 tokens are tool definitions, versus roughly 4,800 of OpenCode's ~6,900.

Zero tools, pure harness

Stripping the tools isolates the system prompt itself. Claude Code's weighs in at 26,891 chars, about 6.5k tokens. OpenCode's is 8,811 chars, about 2.0k tokens. Both harnesses trim their prompt slightly when tools are disabled. Even with no tools at all, Claude Code's instruction set is over three times the size of OpenCode's; the residual is behavioural doctrine, meaning tone rules, safety guidance, task-management instructions, and environment description.

A one-tool task

T2 asked each harness to read a file and summarise it. Both produced correct summaries. Claude Code took 6 HTTP requests and roughly 199,000 cumulative metered input tokens. OpenCode took 4 requests and roughly 41,000, plus one Haiku side call for session titling. Most of those tokens are cache reads billed at a tenth of the input price.

Three things scale with payload regardless: the first-turn cache write, the per-turn read, and context-window consumption, which no cache discount reduces. A 33k-token baseline means every turn starts a sixth of the way into a 200k window before any code enters the conversation.

A multi-step task, where the gap closes

T3, the write-run-test-fix loop, inverted the expectation set by the baselines.

Metric Claude Code OpenCode
Model requests 3 9 (+1 title call)
Tool-calling style parallel batch in one round trip one tool call per turn
Cumulative metered input ~121,000 tokens ~132,000 tokens

Claude Code batched the entire job, two file writes and two script executions, into a single parallel tool round trip. OpenCode made exactly one tool call per turn and took nine. Because the baseline is re-sent on every request, request count multiplies baseline. OpenCode paid its ~7k baseline nine times, Claude Code paid its ~33k three times, and the totals converged. Whole-task input roughly equals baseline times request count, plus conversation growth. A large-baseline harness that batches aggressively and a small-baseline harness that serialises can land in the same place.

Two structural details emerged from the payloads. Claude Code injects an additional block as the conversation progresses, three on the first turn and four by the first tool round trip, so its scaffolding grows with turn count. OpenCode's per-turn marginal payload, roughly 400 to 2,200 chars per turn, is pure conversation content.

Part II. The multipliers

The floor explains a session that starts lean and stays short. Real sessions do neither. We measured each layer that real usage stacks on top.

Multiplier 1. The instruction file

We dropped a real 72KB AGENTS.md from a production repository into the workspace and re-ran T1. The effect is symmetrical and large. Both harnesses gained just over 20,000 tokens per request. OpenCode's metered total went from 13,152 to 33,336. Claude Code's went from 39,005 to 59,243.

The asymmetry is in the mechanics, and it bit us during the experiment. Claude Code 2.1.207 ignored AGENTS.md entirely and only ingested the file when renamed CLAUDE.md, injecting it into the first user message. OpenCode reads either filename and injects it into the system prompt.

Two practical consequences follow. Check which filename your harness actually honours, because an ignored instruction file is silent. And know that a heavy instruction file nearly quadruples a lean harness's baseline; it rides on every request of every session in that repository.

Multiplier 2. MCP servers

We attached public, credential-free MCP servers in one-server and five-server configurations. The schemas are identical across harnesses, so the tax is nearly identical too; roughly 1,000 to 1,400 tokens per small server, per request. Five servers added 4,900 tokens to Claude Code by payload and 6,967 metered to OpenCode, growing the tool counts from 27 to 69 and from 10 to 52.

Small public servers are the gentle case. Production servers with rich APIs ship schemas several times larger, which is exactly what the everything measurement below shows.

One operational footnote. Claude Code silently ignored a project-scoped .mcp.json in print mode until passed an explicit --mcp-config flag. If you assume a server is attached, verify it at the boundary.

Multiplier 3. Framework templates

Story-driven workflow frameworks such as BMAD expand a slash command into a large prompt template of personas, protocols, and checklists. We ran an 8,405-char representative template as the prompt for the same T3 story in both harnesses. The template itself is only about 2,100 tokens, but it enters the conversation history and is re-carried by every subsequent request in the session. A 9-request session re-sends it nine times. Framework tax is template size times request count, and it stacks on top of everything above.

Multiplier 4. Subagents

We asked each harness to fan the work out to two parallel subagents. This is where totals detonate.

Claude Code completed the task with 9 model requests across three distinct request classes. There was the main session with its full ~33k baseline, and five subagent calls each carrying their own bootstrap of a 3,554-char agent system prompt plus 24 of the 27 tools. Cumulative metered input reached 513,000 tokens, against 121,000 for the same work done directly. That is a 4.2x multiplier for one modest fan-out, because every subagent pays its own bootstrap and its transcript is then ingested by the parent.

OpenCode's design here is notably leaner. Its subagent requests carry a reduced profile of a 1,379-char system prompt and 5 tools. Its subagent lane did not complete cleanly through our gateway, so we report the design difference from the captured payloads and leave its totals unquantified.

If your heavy sessions surprise you, this is the first place to look. Delegation is powerful and sometimes correct; it is also the single largest token multiplier we measured.

Multiplier 5. Extended thinking

Thinking output bills at output rates, five times the input rate, and reasoning blocks are carried forward inside the conversation. We attempted to toggle extended thinking in both harnesses and are declining to publish numbers. Our gateway applies its own thinking policy, neither harness's toggle demonstrably survived the path, and anything we quoted would be noise. The mechanism is not in doubt, though. On reasoning-heavy work it compounds with every multiplier above, because the thinking blocks join the history that gets re-sent.

The everything number

Finally, the bridging measurement. We ran T1 again under a real working configuration. For OpenCode that meant eleven MCP servers covering email and calendar, task management, reference management, product analytics, and others, plus the 72KB instruction file. The first request metered 90,817 tokens on a cold cache write, carrying 179 tools and 277KB of schemas, before the user had typed a word.

For Claude Code, four MCP servers plus installed plugins and the same instruction file produced a 311KB payload of roughly 75,000 tokens with 118 tools. After subtracting the gateway envelope, that is roughly a 12x configuration multiplier against OpenCode's ~7,000-token floor. The harness sets the floor; your configuration sets the bill.

The cache economics, honestly

Prompt caching changes the units but not the conclusions. Both harnesses set cache breakpoints correctly. The payload is written once, at a 1.25x premium for the 5-minute TTL, and re-read at a tenth of the price thereafter.

Three costs survive the discount. First, the write itself, re-paid whenever a pause exceeds the TTL. A five-minute think, a meeting, a lunch; each re-primes the full stack at write rates. Second, the read multiplied by request count, which subagent fan-outs and serial tool loops inflate quickly. Third, context-window consumption, which is completely immune to caching. An 85k-token bootstrap occupies more than 40 per cent of a 200k window on every single request, shrinking the room for actual code before compaction kicks in and spends yet more tokens summarising.

Cache stability, the smoking gun

Caching only pays if the prefix stays stable, so we hashed the tools array and system blocks of every request in the dataset. OpenCode emitted byte-identical prefixes across every request and every run. Three separate T1 sessions produced the same tools bytes, the same system bytes, and the same

Comments

No comments yet. Start the discussion.