While auditing wire-level telemetry against local session logs in Claude Code, we found a recurring gap: every 30 seconds, for every actively working background sub-agent whose transcript has advanced, the client forks the sub-agent's entire conversation history back to its own model—usually Opus—just to refresh a short progress label in the UI. Because the request runs with skipTranscript: true, it never appears in the .jsonl files on disk.
.jsonl session logsHow the polling loop works
Inspecting the AgentSummary module in Claude Code shows why the traffic grows so quickly with session length. While a background sub-agent is running, a fixed 30-second timer forks the sub-agent's full conversation history back to the model to generate a 3–5 word progress label.
- Every 30 seconds
setTimeoutfires for each running background sub-agent. - Checks for progressOnce 3 messages exist and a tool turn has completed since the last tick (idle agents with unchanged transcripts are skipped), it triggers a fork.
- Resends the full contextSends the sub-agent's entire conversation history to the sub-agent's own model.
- Skips the disk logExecutes with
skipTranscript: trueandskipCacheWrite: true.
Controlled benchmark on Claude Code
We ran three parallel headless sessions with an OpenTelemetry collector capturing every claude_code.api_request event over a 95-second, five-step sub-agent task: first with default settings, second with a timer pass-through control, and third with the 30-second summary timer disabled.
Live 95-second benchmark: session cost and request breakdown by query_source
claude_code.api_request events over OTLP.Replay across 379 sessions and 199 sub-agent runs
We then replayed the exact 30-second timer and completed-turn deduplication logic across our engineering corpus of 379 sessions and 199 sub-agent runs ($8,132 in visible spend, 99.9% on Opus). In this replay, 148 of the 199 sub-agent runs (74.4%) lasted longer than 30 seconds and would trigger 2,133 hidden summary calls carrying 407.9 million input tokens—an average of 191,214 input tokens re-sent per call just to produce a 3–5 word label.
How each 30-second tick re-sends the growing sub-agent transcript (191K avg tokens/call)
| Corpus slice (replay estimate) | Request share | Spend share |
|---|---|---|
| All 379 sessionsincludes 327 sessions without sub-agents | 5.1%2,133 of 42,172 reqs | 1.03–1.54%$84.57–$127.20 warm · 17.9% if cold |
| 52 sessions with sub-agents148 of 199 sub-agent runs lasted >30s | 5.9%2,133 of 36,326 reqs | 1.17–1.74%$84.57–$127.20 warm · 19.8% if cold |
| Top 10 multi-agent sessionsup to 20 sub-agents per session | 12.1–28.2%up to 306 summary reqs/session | 6.95–13.66%98% warm / 2% cold · up to 67.9% if cold |
Share of API requests consumed by agent_summary in top multi-agent sessions
Reported in the wild: anthropics/claude-code
This pattern has also been surfaced publicly in the anthropics/claude-code repository—highlighting both the volume of hidden agent_summary requests and the lack of a supported flag to turn the polling timer off:
agent_summary calls accounting for 22.7% of all requests and ~18% of weighted tokens in a single session.Workarounds and trade-offs
- Prompt-cache sensitivity: Because each 30-second fork runs with
skipCacheWrite: true, summary calls rely entirely on hitting the sub-agent's existing prompt cache. Whenever a summary call misses the cache, the full transcript is billed at cold input rates. - Undocumented environment variable workaround: A user in
#86879reported in August that settingCLAUDE_CODE_FORK_SUBAGENT=0stops summary polling in interactive sessions as a side effect, with the trade-off that it disablesforksub-agents (which otherwise inherit the parent conversation and share its prompt cache). It is undocumented, so whether it holds depends on your Claude Code version and platform: check before relying on it.
A continuous, endless process
Fixing one 30-second timer or flipping one environment variable solves yesterday's leak, not tomorrow's. This is a continuous and endless process because it will always continue to happen: AI coding tools ship new releases every few days, adding background memory extraction (extract_memories), compaction forks (compact), speculative prompt suggestions (prompt_suggestion) and new sub-agent orchestration loops. Any one of them can silently multiply token consumption or miss the prompt cache while omitting its own footprint from local disk logs.
Chasing individual client flags after the bill arrives is a losing game. The only durable answer is continuous observation on the wire—where every request, cache read, cache write and background loop is measured automatically the moment it happens.
Where ZuzAI fits
ZuzAI sits between your engineering tools and the AI providers, recording every API request, token count, cache hit rate and cost—including hidden background calls that never appear in local transcripts. It runs inside your own tenant across AWS, Azure, GCP and On-Prem.
Published by ZuzAI on October 1, 2026.

