Claude Code's agent status summaries take about 16% of one team's spend, gist says

Flamerix AI published a gist with a small Bun preload script, no-agent-summary.js, that stops Claude Code from generating status-line summaries for background agents. According to the gist's authors, Claude Code sends each background agent's entire transcript to that agent's own model (usually Opus) about every 30 seconds 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 the user's conversation. The authors say there is no setting that turns this off, and that it has been on by default since Claude Code 2.1.232 (August 2026).
The anomaly was detected by DRIM in Claude Code's OpenTelemetry export. Grouping claude_code.api_request events by query_source showed agent_summary costing more than the main conversation itself. The gist is careful about what "spend" means here: it is Claude Code's own per-request estimate (cost_usd), not an invoice. On a subscription, the authors say, what you lose is rate-limit headroom. They add that an issue, #86879, collects four independent measurements of 18 to 26 percent; the gist does not describe those measurements further. In the authors' own telemetry, the weekly share of spend going to agent_summary rose from 3.5 to 7 percent in July to 7.3 percent and then 11.8 percent in the week they picked up 2.1.233, and to about 16 percent by mid-October.
The fix is a preload of about 80 lines, loaded through BUN_OPTIONS=--preload, so the Claude Code binary is not modified. It wraps setTimeout and setInterval. When a callback's source text contains a summarizer anchor, such as the "[AgentSummary] Timer fired" log line, it returns an inert handle instead of arming the timer. Every other timer passes through untouched. The authors explain why they chose a timer hook: the module ships as precompiled Bun bytecode, so editing its JavaScript text inside the binary changes nothing, and the API client does not go through a wrapped globalThis.fetch. Function.prototype.toString still returns a callback's source even when it runs from bytecode, so the timer can be recognised by a string inside it. The inert timer uses exactly 2^31-1 ms, because Node and Bun treat a larger delay as 1 ms.
Installation is a download of the script, then claude daemon stop --any, then starting claude with the preload in BUN_OPTIONS. For permanent use the gist shows shell profile exports, a fish setting, a systemd user environment file, or a wrapper script named claude earlier on the PATH. The daemon must be restarted after install, because the daemon, pty host and pre-warmed bg-spare sessions inherit the environment of the client that started the daemon. Headless runs (claude -p, cron, CI, editor integrations) need the hook too.
The authors say they run it under every Claude Code process on their machine (2.1.301). Since then there have been zero agent_summary requests, and no other side query grew to take its place. Subagents, background agents, forked skills and background sessions run normally; only the summary fork is skipped. The visible change is that the per-agent panel status stops updating, and the SDK's task_progress has no summary. Overhead is one Function.prototype.toString per distinct timer callback, cached in a WeakMap; claude --version went from about 10 ms to about 17 ms in one measurement.
The gist also lists why simpler options do not work. The documented agentProgressSummaries SDK option only turns summaries on; false changes nothing, and the undocumented CLAUDE_CODE_AGENT_PROGRESS_SUMMARIES can only enable them too. The interval comes from a per-model-family server flag clamped to 30 to 240 seconds, so the default is already the minimum and no value disables the timer. DISABLE_NON_ESSENTIAL_MODEL_CALLS does not occur in the binary at all. CLAUDE_CODE_FORK_SUBAGENT=0 and CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 stop the summaries, but only by taking fork subagents or background agents with them. The prompt cache makes the calls cheaper, not cheap: about 98 percent re-read the transcript from cache, while the roughly 2 percent that hit a cold cache carry over a third of the cost. Cost tools that read transcripts do not see these requests, since they are not written to the session logs on disk (#104358); only the OpenTelemetry export shows them. Finally, the authors note that Claude Code 2.1.310 ships a cheaper "short" mode, about 2k tokens of notes instead of the full transcript, optionally written by a smaller model. It is switched off; the default is still the full transcript, and only server flags can change it.
Key facts
- The gist's authors say Claude Code sends each background agent's whole transcript to its own model about every 30 seconds to get a 3-5 word status-line description that never reaches the conversation.
- In the authors' own telemetry, agent_summary's weekly share of spend (Claude Code's cost_usd estimate) grew from 3.5 to 7 percent in July to about 16 percent by mid-October; issue #86879 collects four measurements of 18 to 26 percent.
- no-agent-summary.js is an MIT-licensed Bun preload of about 80 lines that wraps setTimeout and setInterval and leaves the Claude Code binary unmodified; the authors report zero agent_summary requests since using it on 2.1.301.
- The summaries have been on by default since 2.1.232 (August 2026), and the authors say no setting turns them off; the obvious environment variables only stop them by also disabling fork subagents or background agents.
- Tested on Linux with Claude Code 2.1.257 to 2.1.312; macOS and Windows are untested, and an update can silently undo the hook.
Why it matters
If the authors' account is right, a feature that produces a three-to-five-word label is one of the larger line items in a Claude Code bill for people who run background agents. In their telemetry agent_summary cost more than the main conversation itself, and its share climbed from 3.5 to 7 percent in July to about 16 percent by mid-October. The cost comes from resending whole transcripts rather than from the output, and the result only updates a status line. The authors also point out that a cheaper "short" mode already ships in 2.1.310 but is switched off.
Who it affects
People who run background agents or subagents in Claude Code, including headless uses such as claude -p, cron, CI and editor integrations. On a subscription, the authors say, the loss shows up as rate-limit headroom rather than money. Users who track spend with tools that read session logs on disk would not see these requests, because they are not written there; only the OpenTelemetry export shows them.
How to use it
The gist is released under the MIT licence. The steps: download no-agent-summary.js to a stable path, run claude daemon stop --any, then start claude with BUN_OPTIONS containing --preload and the absolute path to the script. For every process, set BUN_OPTIONS in a shell profile, fish config or systemd user environment file, or put a wrapper named claude earlier on the PATH. To check it works, run claude --version with CC_AGENT_SUMMARY_LOG set and look for "preload active mode=off"; then run a background subagent for a minute or two and look for "summary timer #1 suppressed" in the log. If you export OpenTelemetry, query_source = agent_summary should stay at zero. Setting CC_AGENT_SUMMARY_MODE=pass loads the hook but arms every timer, which brings the summaries back and works as an A/B check. The visible cost is that the per-agent panel status stops updating.
How solid is it
The evidence is self-reported. The 16 percent figure comes from the authors' own telemetry, and the anomaly was detected by DRIM in the OpenTelemetry export; the source does not explain how DRIM relates to Flamerix AI. The 18 to 26 percent range comes from four measurements collected in issue #86879, with no setups or bases described in the gist. The shares are of Claude Code's own cost_usd estimate, not of tokens and not of invoiced money. The source gives no dollar amounts. The authors describe a static check of the extracted bundle and a live test on a Linux x64 binary, where the fork happened 5 times out of 5 with the hook only loaded and 0 times with it switched to off. No response from Anthropic is quoted.
Risks and caveats
The hook matches by source text inside the timer callback. A rename of the log line or query-source id, a callback passed via bind, strings moved to a shared constant, or a timer moved to an unwrapped API would make it match nothing, and the summaries would silently return, so the authors say to re-run the verification after every update. Linux is the only tested platform; on Windows the hook most likely never installs. The daemon must be restarted or it keeps spawning unhooked sessions. The gist's disclaimer says changing a client's runtime behaviour may conflict with the terms of the service, that checking this is the user's job, that the software is provided without warranty, and that the project is independent of Anthropic.
“describe your most recent action in 3-5 words”
— Claude Code's summary prompt, as described by the gist's authors at Flamerix AI