Session resume (--continue) invalidates entire prompt cache, causes massive rate limit consumption

Resolved 💬 11 comments Opened Apr 2, 2026 by taekim34 Closed Apr 3, 2026

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

View original on GitHub ↗

This issue has 11 comments on GitHub. Read the full discussion on GitHub ↗