groundy
Models & Research

How to Measure Claude Code's Per-Turn Token Overhead: Status Lines, MCP Tools

Claude Code token overhead splits into background agent summaries and in-context MCP schemas. Measure both via OpenTelemetry to isolate costs and optimize cache usage.

Published 6 references
Two green resin dinosaurs stand apart on ivory. A squat dinosaur fits a yellow piece into its belly; a long-necked dinosaur holds a blank yellow speech bubble above its curled tail.
On this page9 sections

The claim that a three-word Claude Code status line burns 15-20% of your session tokens reads as a statement about per-turn context growth, but the source describes something else, and says so itself. The community gist that originated the figure describes a feature called agent_summary: roughly every 30 seconds, for every background agent, Claude Code sends that agent’s entire transcript to its model, usually Opus, and asks it to describe its most recent action in 3-5 words. But the gist also states that the answer “never reaches the model or your conversation.” Whatever this feature costs, it is not per-turn context growth. It is a separate stream of background API calls whose size grows with each agent’s transcript, which puts the status-line cost in a different channel from the MCP tool schemas it shares headline space with.

That distinction is the practical finding that should shape everything you do next. If you are on a usage-based plan and your bill climbed after Claude Code 2.1.232 (August 2026), when the gist says this feature became default-on with no off switch, you are looking at two different cost channels that need two different measurements: background summarization calls on one side, and in-context per-turn overhead (system prompts, MCP tool schemas, reminders) on the other. A single “overhead percentage” conflates them.

What the status-line figure actually describes

Read the gist as a mechanism report rather than a benchmark. Per the gist’s own description:

Every ~30 seconds, for every background agent, Claude Code sends that agent’s entire transcript to the agent’s own model (usually Opus) and asks it to “describe your most recent action in 3-5 words”. The answer only updates the agent’s status line in the agents panel; it never reaches the model or your conversation. There is no setting that turns it off, and since 2.1.232 (August 2026) it has been on by default.

Three properties matter for your audit. First, the cost scales with the number of background agents and with transcript length, not with your visible conversation. A long-running background agent accumulates a large transcript, and re-sending that transcript every 30 seconds is O(transcript) spend at a fixed cadence. Second, the output is tiny and confined to the UI. Third, because it is a model call, it still bills input tokens at whatever caching applies to that call: the gist estimates that about 98% of these calls re-read the transcript from cache, and that the ~2% hitting a cold cache carry over a third of the feature’s cost. Those calls are also easy to miss, and not by accident: per the gist, they “are not written to the session logs on disk (#104358); only the OpenTelemetry export shows them.”

So the 15-20% figure is best treated as a statement about total session spend under a particular workload, most plausibly one with several long-lived background agents. Spend has a precise meaning here: per the gist, it is Claude Code’s own per-request cost_usd estimate, not an invoice, and on a subscription what you lose is rate-limit headroom. It is a gist-sourced claim rather than an uncorroborated number: the gist links four independent measurements of 18–26%, corroboration I have not independently checked, and the independent range sits a few points above the headline. Whether any of it generalizes to your setup is exactly what your own telemetry can answer. Until it does, treat it as a hypothesis with partial corroboration, not a budget line.

Two cost channels, two measurements

The other named sink in the title, MCP tool schemas, works through the opposite channel. Tool schemas are injected into the model’s context and, in the eager-injection deployments the preprint’s audits measure, re-sent with every turn of the conversation. According to a 2026 preprint on tool-token overhead, “Empirical audits consistently place this overhead between 15,000 and 55,000 tokens per turn in typical four-to-six-server deployments, reaching >>150k with aggressive tool sprawl.” Those are third-party audits aggregated in a preprint, not an Anthropic-published breakdown, so treat the range as reported rather than definitive. Even at the low end, though, 15,000 tokens of schema text re-read every turn dwarfs anything the three-word status line could cost you in context, which per the gist is nothing: its output stays in the UI.

This is why the audit has to split channels:

  • Background calls (agent_summary): periodic, per-agent, transcript-sized inputs, output never enters context. Find them by grouping claude_code.api_request events by query_source in the OpenTelemetry export; they do not appear in the session logs on disk, the gist reports.
  • In-context overhead: system prompt, tool schemas, subagent definitions. The system prompt is assembled into context every turn; the rest are candidate sinks that enter context when loaded or dispatched rather than riders of every turn. Per an analysis of Claude Code’s design space, tool schemas by default load only when a tool is needed, and a subagent definition’s markdown body serves as the spawned agent’s system prompt, entering context on dispatch; only the dispatching tool’s schema plausibly rides every parent turn.

The cache interaction is where money hides. A prompt-caching evaluation for long-horizon agentic tasks demonstrates the boundary mechanic directly: appending a UUID after the system prompt “breaks the cacheable prefix at this boundary,” so dynamic content such as tool results does not contribute to the cache. Prompt caching bills a re-read of the static prefix cheaply; anything after the first changing byte is billed as a fresh read. Client text that changes every turn, if it sits early in the prompt, forfeits cache coverage for everything downstream. A sink that looks small in raw tokens can be expensive purely because of where it sits.

The audit procedure

One documented fact about visibility shapes the procedure: these requests “are not written to the session logs on disk (#104358); only the OpenTelemetry export shows them,” and the docs section on background token usage doesn’t list them either, the gist reports. So the mechanical steps below are a procedure to run against your own reporting, with each step tied to a mechanic the cited work establishes. Adjust the extraction details to whatever your plan’s usage export actually provides.

  1. Establish a baseline turn. Start a fresh session with no MCP servers configured and no background agents. Send one trivial turn and record input tokens billed, cache-read versus cache-write split if your report shows it, and output tokens. This gives you the floor: system prompt plus built-in tool definitions.
  2. Enumerate client-side text sources. Claude Code ships a built-in Statusline-setup subagent for terminal status line configuration, and users add custom subagents via .claude/agents/*.md files, with plugins contributing further agent definitions, per an analysis of Claude Code’s design space. Count these files and their sizes; each is a candidate context sink to measure, not a confirmed per-turn rider.
  3. Add MCP servers one at a time, then invoke a tool from each. Enable one server, re-run the same trivial turn, and then send a turn that calls one tool from that server; the delta across those turns is that server’s schema cost. The second turn matters because per an analysis of Claude Code’s design space, “full schemas are loaded on demand,” so a turn that never calls a tool carries tool names and deferred definitions rather than the full schema payload. Read the 15,000-55,000 tokens-per-turn range reported for four-to-six-server deployments as a ceiling for eager-injection deployments, where the full catalog is re-serialized on every request, rather than as a default expectation under on-demand loading. If your per-server numbers sit far above the range’s implied average, a verbose schema or a sprawl of rarely used tools is the likely cause.
  4. Measure cache behavior across consecutive turns. Send the same prompt twice and check whether the second turn reports cache reads. If a changing element your own configuration introduces (a timestamp, a session identifier, a UUID in the system prompt) sits before your static content, the cache-boundary finding from the caching evaluation predicts you will see full re-reads instead of cache hits. That is your smoking gun for volatile-prefix overhead. Be clear about what this step is not: per the gist, Claude Code’s agent status line is UI-only, its summary text never reaching the model or your conversation, so this is a check for volatile prefix text you introduce, not a presumed status-line cost.
  5. Isolate background calls. The primary instrument is the OpenTelemetry export, because that is the only reporting surface where these calls appear. Group claude_code.api_request events by query_source; this is how the gist’s authors detected the anomaly, measuring agent_summary at 16.4% of all Claude Code spend versus 15.7% for the main conversation in the week before their fix, and 19.7% of all API requests. Without that export, an upper-bound estimate is transcript size times two calls per minute per agent at the 30-second default cadence the gist describes.
  6. Vary session length and agent count. The gist’s claim, if it holds anywhere, should strengthen with more background agents and longer transcripts. Your context overhead, by contrast, grows with conversation length and server count. Plotting both against these axes tells you which channel dominates your bill.

One scope warning on step 3: the schema numbers you measure depend heavily on which servers you run and how the sample was drawn. An August 2026 random draw from the MCP registry, seeded 20260819 from the 2026-08-22 census snapshot, found 2,766 advertised tools across 195 running servers, with optional safety annotations omitted at the tool level 58.8% of the time on the random draw versus 41.5% on a curated frame. Curation flatters these figures, so a vendor benchmark showing “lean” servers may not describe the registry population you actually install from. Measure your servers, not the benchmark’s.

Which sinks are cacheable, and which break the cache every turn

Combining the boundary mechanic from the caching evaluation with the channel split above gives a working map. The cache-exposure column applies that mechanic to sinks the caching paper does not itself test, so verify positions against your own transcripts: the evaluation demonstrates the boundary on its own agentic benchmark, not on Claude Code’s prompt layout.

Overhead sinkCost channelChanges per turn?Cache exposureTrim lever
System prompt, static instructionsIn-contextNoCacheable if nothing volatile precedes itRarely worth trimming; keep it stable
MCP tool schemasIn-context; 15k-55k tokens/turn reported as an eager-injection ceilingNo, but bulk scales with server countCacheable as static prefix where injected; cost is size, not volatilityDrop unused servers; gating where available
Subagent definitions (.claude/agents/*.md, plugins)In-context when loadedNoCacheableRemove unused definitions
Volatile text in the system prompt (timestamps, session IDs)In-contextYesBreaks the cacheable prefix at its position if earlyMove volatile text late in the prompt or drop it
agent_summary status updatesBackground API calls, ~30s per agentYes (each call)Separate billing channel; ~98% of calls re-read the transcript from cache, per the gistNo official off switch per the gist; reduce background agents

The row that most budgets miss is the fourth. The caching evaluation documents the artifacts that create it: common cache breakers include timestamps, datetime strings, session identifiers, or user-specific information embedded in the system prompt. None of these is large in a token count; the boundary mechanic above is what makes them expensive.

When each trim pays off

Cut MCP servers first. The evidence-backed magnitudes point here. A deployment carrying the reported 15,000-55,000 tokens per turn under eager injection pays that schema cost on every conversational turn, and step 3 attributes it server by server. Audit your per-server deltas and remove servers your sessions rarely invoke. This trim is safe, reversible, and attacks the largest documented sink.

Stabilize volatile prompt text second. If step 4 shows cache misses caused by a changing element, relocating or removing that element converts full re-reads into cache reads on every subsequent turn. The payoff scales with prefix size, so it compounds with your MCP footprint rather than competing with it.

Address agent_summary only after measuring it. The gist ships a Bun preload workaround to disable the feature, and it supplies the measurement to run alongside it: group claude_code.api_request events by query_source in the OpenTelemetry export, where “query_source = agent_summary should stay at zero; this is the only check that catches every failure mode.” Unofficial client patching still carries its own maintenance and breakage risk on a client that updates frequently. I would first read the query_source split from your own telemetry. If you run many long-lived background agents, the cost may justify a workaround; if you rarely use background agents, the preload is a fix in search of a problem.

Do not budget on simulated savings. The same tool-overhead preprint reports that its proposed Tool Attention mechanism cut measured per-turn tool tokens by 95.0% (47.3k to 2.4k) in simulation and raised effective context utilization from 24% to 91%. Striking numbers, but the paper itself states that its end-to-end figures for task success, latency, cost, and reasoning quality “are not measured on live LLM agents” and are projections from measured token counts plus published telemetry. If a host-level dynamic tool-gating feature ships in your client, measure it with the same audit; do not pre-spend the 95%.

Recognize the ceiling on client-side trimming. A paper on MCP resource utilization argues that “per-server prompt engineering is therefore a workaround rather than a fix,” and that MCP host applications should provide an explicit mechanism placing server instructions ahead of tool selection in the client LLM’s deliberation. The structural fix belongs to the host, not to your config files. Trimming buys you savings now; it does not replace pressing for tool gating at the client level.

What the evidence cannot settle

It is worth being plain about the status of each magnitude before you act. The 15-20% status-line figure comes from a community gist whose described mechanism is background calls, not context tokens, and it will vary with agent count, transcript length, and session shape. The 15,000-55,000 token range aggregates third-party audits cited in the tool-overhead preprint, whose 95% reduction figure is a simulation projection. None of these is an Anthropic-published breakdown of Claude Code’s prompt assembly, and the visibility gap is documented rather than hypothetical: per the gist, these requests are not written to the session logs on disk, and the docs section on background token usage doesn’t list them. That is why the audit procedure above leans on the OpenTelemetry export rather than a script. Version behavior is also drifting, per the gist’s timeline: the default-on change is tied to 2.1.232, the summary interval became server-tunable between 30 and 240 seconds in 2.1.300, and 2.1.310 shipped a cheaper short mode, about 2k tokens of notes instead of the full transcript, switched off by default.

That is precisely why the procedure matters more than any of the numbers. The durable finding is not a status-line percentage or a schema token count; it is that usage-based agent plans have two cost channels with different scaling laws, and only one of them is visible in your conversation. Split your telemetry by channel, measure cache-hit status on consecutive turns, and trim what your own numbers indict. If your audit does land in the reported range from background calls, the query_source grouping that produced the gist’s numbers is cheap to replicate, and a readout published with your workload shape says more than another headline percentage.

Frequently Asked Questions

What is the reported token overhead for MCP tool schemas per turn?

According to a 2026 preprint on tool-token overhead, “Empirical audits consistently place this overhead between 15,000 and 55,000 tokens per turn in typical four-to-six-server deployments, reaching >>150k with aggressive tool sprawl.”

Does the agent_summary status line text enter the model’s context?

The answer only updates the agent’s status line in the agents panel; it never reaches the model or your conversation. There is no setting that turns it off, and since 2.1.232 (August 2026) it has been on by default.

References

Follow the links in the article for context. The supporting material is collected here for further reading.

  1. Community gist on Claude Code agent_summarygist.github.comAccessed
  2. 2026 preprint on tool-token overheadarxiv.orgAccessed
  3. Analysis of Claude Code's design spacearxiv.orgAccessed
  4. August 2026 random draw from the MCP registryarxiv.orgAccessed
  5. Paper on MCP resource utilizationarxiv.orgAccessed

Join the discussion

Share a useful perspective or ask a question about this article.

Discussion guidelinesComments privacy