Run background agents in Claude Code and every 30 seconds, for each agent, the tool ships that agent’s entire transcript plus the full tool schema to the agent’s own model—usually Opus—and asks it to describe its most recent action in three to five words. The answer fills the status line in the agents panel. It never reaches the model, and it never reaches your conversation.
Flamerix AI measured this in Claude Code’s OpenTelemetry export. Group claude_code.api_request by query_source and agent_summary costs more than the main conversation does: 16.4% of Claude Code’s own estimated weekly spend against 15.7% for the actual chat. Roughly one API request in five (19.7%) was a status line. 96% of that spend ran on Opus, at a ratio of about 9,000 input tokens per output token.
Four more measurements, open since mid-August
Flamerix is not alone. Issue #86879 in the Claude Code repository has been open since August 15 and collects four independent measurements between 18% and 26%. Its author reconstructed a four-hour session with 27 subagents and 1,496 requests from raw payloads: 339 of them were agent_summary, together 22.2% of raw tokens and 22.7% of all requests—for 21,966 output tokens of cosmetic status text in total, about 65 per call.
The shape of the thing explains the size. Cost grows with how many agents run in parallel and how long they run, not with useful work. Three concurrent subagents pay six of these calls a minute.
There is no way to switch it off
The documented SDK option agentProgressSummaries defaults to false. In the shipped bundle it is one term of an OR, and every code path that writes it writes true. The interval comes from a server flag clamped to 30–240 seconds; the default is already the minimum, and no value disables the timer. DISABLE_NON_ESSENTIAL_MODEL_CALLS does not appear in the binary at all. Two other variables do stop it, but they take fork subagents or background tasks with them.
So Flamerix published no-agent-summary.js, a Bun preload of about 70 lines. It wraps only the global setTimeout and returns an inert handle when a callback’s source text carries a summarizer anchor. The binary stays untouched. After the hook the share dropped to zero, and every other request in the session was byte-identical—the summary call forks context, denies all tools, runs one turn and writes nothing to the transcript.
Invisible because the logs don’t know about it
There is a plain reason nobody noticed for months: these requests are not written to the session logs on disk. Check your consumption with any tool that reads transcripts and you will not see them. Only the telemetry export does.
Anthropic knows about the problem. 2.1.310 shipped a cheaper short mode that sends roughly 2,000 tokens of notes instead of the whole transcript, optionally written by a smaller model. It is not the default, and only server flags can change that. The changelog for 2.1.314, published overnight, says nothing about it. A switch for something that causes one request in five would be a single line.