[BUG] Waking a parked subagent re-caches its entire context: only the system prefix is served from cache, even minutes later within TTL

Status Open
Reported on v2.1.233
Maintainer reply None cached
Activity 3 comments · opened Aug 16, 2026

Summary

When a stopped/parked subagent is woken (by SendMessage from its parent, or by a background-task completion notification), the next API request serves only the ~6K-token system prefix from cache and re-writes the entire remaining conversation at cache-write rates. This happens even when the wake arrives minutes after the subagent's last turn, well inside the cache TTL, so it is not cache expiry: the conversation-level cache breakpoints appear to be discarded when the subagent's request is reassembled on wake.

Environment

  • Claude Code 2.1.233, macOS (darwin 24.6.0)
  • Session with 1-hour prompt-cache TTL
  • Multi-agent orchestration: a parent session spawning claude-type background subagents that park between turns (waiting on child agents / background test runs) and are woken by SendMessage or task notifications

Evidence (from session transcripts, usage deduped by message id)

One subagent's wake sequence, all within a single 1h-TTL session. Every wake shows cache_read_input_tokens pinned at exactly the system-prefix size while the whole conversation is re-written:

| wake (UTC) | gap since last turn | cache_read | cache_creation |
|---|---|---|---|
| 20:35:37 | 11m | 6,007 | 82,903 |
| 20:39:10 | 2m | 6,007 | 97,752 |
| 20:43:06 | <1m | 6,007 | 128,121 |
| 20:51:54 | 5m | 6,007 | 150,735 |
| 21:03:19 | 11m | 6,007 | 152,653 |
| 21:21:26 | 18m | 6,007 | 153,767 |

The same signature appears in every parked subagent of the session: 12 subagents, 54 full-context rewrites, 5.2M tokens re-cached at write rates in a 2-hour run. During a subagent's normal working turns, incremental caching behaves correctly (large cache reads, small writes); the full rewrite happens only on the first request after a wake.

Note the 2-minute and sub-minute gaps: no TTL explains those. The cache_read value being exactly the system-prefix size every time suggests the wake path rebuilds the request with a cache breakpoint after the system prompt but without the breakpoints that covered the accumulated conversation.

Repro outline

  1. Spawn a background subagent (claude type) that does some work (grow its context to ~100K), then stops its turn to wait (e.g. on a background task).
  2. A few minutes later, SendMessage it from the parent.
  3. Compare the woken request's usage against the subagent's prior turns: prior turns show cache_read ≈ full context; the wake shows cache_read ≈ system prefix only and cache_creation ≈ full context.

Expected

A wake within the TTL should be an append: cache_read ≈ the full prior context, cache_creation ≈ the injected message plus normal growth.

Impact

In orchestration patterns where subagents park between phases (parent pings, task-completion wakes), this multiplies input spend: in the measured session the rewrites alone were roughly a quarter of total weighted token cost. It also penalizes exactly the workflows the docs encourage (backgrounded long runs, parent/child messaging).

Related, but distinct

  • #74318 measures subagent cache-TTL strategy (5m vs 1h trade-offs). This report is orthogonal: within any TTL, the wake path discards conversation breakpoints entirely.
  • #81389 asks for parent-cache inheritance at spawn. This is about a single subagent's own cache across its own turns.

View original on GitHub ↗

3 Comments

ArshansGithub · 1 month ago

Subagent-wake re-caching is #83913 (hook context dropped on the rebuild that the wake triggers); teammate-opened turns missed at 10× the typed-turn rate on 2.1.252 and were all hits on 2.1.259 in my capture. Suggest closing as fixed in 2.1.259. Details: https://github.com/anthropics/claude-code/issues/91707.

lucascampolina · 1 month ago

Same signature on Claude Code 2.1.258 with claude-fable-5-1 subagents, but without a park/wake: plain background subagents (Agent tool, run_in_background: true, 8 in parallel doing WebSearch/WebFetch/Write) re-cache the whole conversation on ordinary working turns. cache_read_input_tokens pinned at the 33,578-token system prefix, cache_creation = the rest of the context, always in the ephemeral_5m bucket:

| time (UTC) | agent | call # | cache_creation | cache_read | gap since previous response |
|---|---|---|---|---|---|
| 15:41:02 | a3ab40ae | 8 | 213,484 | 0 | 3.5 min |
| 15:57:58 | a9cd220c | 9 | 212,879 | 33,578 | 1.5 min |
| 16:03:25 | a629058a | 14 | 431,885 | 33,578 | 5.7 min |
| 16:09:27 | ad6e8ac3 | 10 | 263,804 | 33,578 | 5.2 min |
| 16:15:45 | ad6e8ac3 | 11 | 300,061 | 33,578 | 6.3 min |

10 rewrites, 2.88M cache-write tokens, in under 40 minutes on 2026-09-03; several agents did it on two consecutive turns. The request right after each rewrite reads the full context again (e.g. 304,655 read / 1,595 written), so the breakpoints come back; they just do not survive a Fable 5.1 turn. Two of the gaps above (1.5 and 3.5 min) are inside the 5m TTL, which looks like the loss you describe here rather than expiry; the rest line up with Fable 5.1 turns simply outrunning the 5m bucket. Zero such rewrites on claude-opus-5 (1,720 subagent calls) and claude-fable-5 (179) subagents in the same week.

Filed the Fable 5.1 angle with request IDs and the cross-model table as #92090; linking here since it is likely the same underlying cache handling for subagents.

PearGod · 27 days ago

Another data point, same signature, on 2.1.276 / Linux (NixOS) / claude-fable-5-1, and with a clean negative control.

Setup: one interactive session spawned 14 background Agent sub-agents over a morning (a security-sweep orchestrator with 11 research arms, plus two build/review agents). Only two of the 14 ever received a background-task completion notification (they had spawned children of their own). Usage from the sub-agent transcripts, assistant records deduplicated by message id:

| sub-agent | calls | received task-notification wakes | full-context re-writes mid-run | tokens re-written |
|---|---|---|---|---|
| build agent (Fable 5.1) | 209 | 5 | 2 — both on the first request after a wake | 237,127 + 279,607 |
| research arm with children (Opus 5) | 39 | 1 | 5 (1 after a wake, 4 after its own child spawns) | 600,324 |
| the other 12 (no wakes) | ~1,000 total | 0 | 0 | 0 |

The build agent's two re-writes: cache_read 5,515 and 0, cache_creation 237k and 279k, immediately after a [SYSTEM NOTIFICATION] task-notification user record (isMeta: true). The preceding request in each case was a normal incremental turn (cache_read ~238k / ~279k, cache_creation 3k / 0.7k). Gaps were 9 s and 7 min, both well inside the 1h TTL. Every other request in that agent cached incrementally.

Cost that morning: ~1.1M cache-write tokens attributable to the wake path, ~7% of the day's weighted spend. Cross-ref #94728, which captures the messages_changed diagnostic for the same resume path.