Session resume (--continue) invalidates entire prompt cache, causes massive rate limit consumption
Summary
Resuming a session with --continue or /resume completely invalidates the prompt cache, even when re-entering within seconds. On a long session with a large prompt, this forces a full cache_creation of 400-500k tokens each time — silently burning through rate limits.
What happened
On a 1M context Opus 4.6 session with ~500k prompt, I exited and re-entered with --continue a few times. Each time, cache_read dropped to 0 and the entire prompt was re-cached from scratch — even though the re-entry happened within 2-3 seconds (well within 5-minute cache TTL).
Additionally, the prompt size barely changed after re-entry, meaning whatever restructuring happened during reload provided no benefit — it just destroyed the cache.
All resume methods affected (controlled tests)
Tested with the same session, varying only the resume method and flags:
Test 1: --continue --dangerously-skip-permissions (12s gap)
Before: cr: 172,301 cc: 1,344
After: cr: 0 cc: 174,210 ← full re-cache
Test 2: --continue only (20s gap)
Before: cr: 176,193 cc: 0
After: cr: 0 cc: 176,730 ← full re-cache
Test 3: /resume (interactive resume, ~2.5h gap)
Before: cr: 160,149 cc: 314
After: cr: 0 cc: 156,682 ← full re-cache
All three: cache_read: 0, full re-cache. The --dangerously-skip-permissions flag is irrelevant — it's the resume/continue mechanism itself.
Raw Data (deduplicated by msg_id, from JSONL session log)
Spike 1: session resume after ~4h sleep (expected)
04:18:37 cr: 389,000 cc: 210 out: 640 stop:end_turn ← last turn before sleep
... ~4 hours gap (cache TTL expired — this one is expected)
08:08:09 cr: 0 cc: 0 out: 0 stop:stop_sequence ← session resume
08:09:47 cr: 0 cc: 367,175 out: 822 stop:tool_use ← 367k full re-cache (expected)
Spike 2: /exit → --continue, 2 seconds apart
09:04:15 cr: 499,517 cc: 486 out: 521 stop:end_turn ← last turn before /exit
... /exit at 09:04:29, --continue at 09:04:31 (2 SECONDS)
09:04:31 cr: 0 cc: 0 out: 0 stop:stop_sequence ← session reload
09:05:13 cr: 26,691 cc: 470,381 out: 1,352 stop:tool_use ← 470k re-cache! (WHY?)
Spike 3: /exit → --continue, 3 seconds apart
09:40:19 cr: 561,082 cc: 987 out: 289 stop:end_turn ← last turn before /exit
... /exit at 09:40:21, --continue at 09:40:24 (3 SECONDS)
09:40:24 cr: 0 cc: 0 out: 0 stop:stop_sequence ← session reload
09:42:59 cr: 26,691 cc: 511,847 out: 1,649 stop:tool_use ← 512k re-cache! (WHY?)
Messages in JSONL right before each spike
Spike 2 context:
/exit command logged
file-history-snapshot
custom-title
agent-name
file-history-snapshot
→ stop_sequence "No response requested."
→ cr:0 cc:470,381
Spike 3 context:
/exit command logged
file-history-snapshot
custom-title
agent-name
file-history-snapshot
→ stop_sequence "No response requested."
→ cr:0 cc:511,847
Before/after comparison
Before /exit → After --continue (first turn)
prompt: 500k → 497k (-0.6%) cache_create: 470,381 (entire prompt re-cached)
prompt: 561k → 538k (-4%) cache_create: 511,847 (entire prompt re-cached)
Impact
In a 2.6-hour morning window:
- 3 session resumes consumed ~1.43M cache_creation tokens
- Actual useful output during same period: ~155k tokens
- cache_creation was 9x the actual output
- Hourly rate limit cost: 920k/hr vs normal 412k/hr (2.2x increase)
Root Cause
Per @ArkNill's analysis: the deferred_tools_delta feature introduced in v2.1.69 reorders tool results when reconstructing the conversation for resume, which breaks the cache prefix and forces a full re-cache. See #34629 and https://github.com/ArkNill/claude-code-cache-analysis.
Environment
- Model: claude-opus-4-6 (1M context)
- Platform: macOS
- Multiple plugins/skills (~40k system prompt tokens)
- Session duration: ~34 hours (long-running)
Related
- #34629 — Prompt cache regression in --print --resume since v2.1.69
- #40524 — Conversation history invalidated on subsequent turns
- #42136 — Aggressive context compaction on 1M context
- #38350 — Abnormal rate limit consumption
This issue has 11 comments on GitHub. Read the full discussion on GitHub ↗