[BUG] Claude Code 2.1.218+ no longer requests 1h prompt-cache TTL — every 5+ min gap forces full cache rewrite

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

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (with this evidence — see Additional Information for related reports)
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

Starting with Claude Code 2.1.218, the client no longer requests the 1-hour prompt-cache TTL (cache_control: {type: "ephemeral", ttl: "1h"}). Every cache_creation entry in session transcripts lands entirely in the 5-minute bucket (ephemeral_5m_input_tokens), with ephemeral_1h_input_tokens = 0 across all records.

This means the prompt cache expires after 5 minutes of idle time instead of 1 hour. Any gap longer than 5 minutes forces a full cache rewrite on the next turn, paying the full 1.25× write premium for content that was cached moments earlier.

This affects both user-driven and agentic workloads:

  • User-driven: reading a diff, reviewing a PR, switching to another session, or thinking through a problem — all routinely exceed 5 minutes. The 1h TTL made these invisible to the cache; the 5m TTL makes every pause a full rewrite.
  • Agentic: tool calls that take more than 5 minutes are standard in agentic use — running a test suite (thousands of tests), delegating a 10-20 minute investigation to a subagent, or waiting on a web fetch. With the 5m TTL, every such gap forces a full cache rewrite. The agent has no way to avoid it without avoiding the workload itself; "don't make tool calls that take more than 5 minutes" is not a viable constraint for agentic use and effectively negates the agent's ability to run long-running operations.

What Should Happen?

Claude Code 2.1.215 and earlier used the 1-hour TTL for interactive sessions (measured: 157/157 records had ephemeral_1h_input_tokens > 0 in a 2.1.215 session). The 1h TTL is the right default for interactive use: a single 2× write amortizes across every turn of an afternoon session, versus repeated full-price 1.25× rewrites on every 5-minute pause.

The 1h TTL should be restored for interactive sessions (or exposed as a setting, as requested in #74075).

Error Messages/Logs

Measured from session transcripts (~/.claude/projects/<hash>/<session>.jsonl, per-record message.usage.cache_creation):

2.1.215 (before):

ephemeral_1h_input_tokens: nonzero (157/157 records)
ephemeral_5m_input_tokens: 0 (0/157 records)
→ 1h cache only

2.1.222 (after):

ephemeral_1h_input_tokens: 0 (0/347 records)
ephemeral_5m_input_tokens: nonzero (347/347 records)
→ 5m cache only

Steps to Reproduce

  1. Start an interactive Claude Code session on 2.1.218 or later.
  2. Run a substantive multi-turn workflow so the prompt cache accumulates a large prefix (>100k tokens).
  3. Inspect ~/.claude/projects/<hash>/<session>.jsonl. For every type: "assistant" record, check message.usage.cache_creation:
  • ephemeral_1h_input_tokens will be 0 on all records
  • ephemeral_5m_input_tokens will be nonzero
  1. (Optional) Compare with a session from 2.1.215 or earlier: ephemeral_1h_input_tokens will be nonzero on all records.

Claude Model

Other

Specifically: Claude Fable 5 and Claude Opus 5 (both exhibit the same 5m-only behavior on 2.1.222).

Is this a regression?

Yes

2.1.215 and earlier used the 1h TTL for interactive sessions. The regression landed in 2.1.218.

Last Working Version

2.1.215

Claude Code Version

2.1.222

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

iTerm2

Additional Information

Economic impact (measured, not inferred):

Scanned 236 primary session transcripts (2026-07-21 to 2026-08-05, Claude Code 2.1.215 to 2.1.222) with a drop-detection script. The script dedupes by consecutive same-cache_read + same-model records, then detects a "drop" where cache_read decreases between adjacent deduped records. Drops are classified by cause: model switch (safeguard-triggered), TTL expiry (gap ≥ TTL), or invalidate (gap < TTL, same model — the #78660 / #81967 class).

TTL switched from 1h to 5m at 2.1.218 (19/28 sessions on 1h in 2.1.215 → 16/17 sessions on 5m in 2.1.218). By 2.1.219 onward, effectively all sessions are 5m-only.

Cost breakdown — the "1h savings" column estimates what could be saved if the 1h TTL were still in use: every gap-5-to-60-min drop that currently forces a full 5m cache rewrite would instead be a cache_read (0.1× instead of 1.25× write). Ratios are unit-price-invariant; the dollar figures use Fable 5 API rates (input $10/MTok, cache_read $1/MTok, cache_write 5m $12.50/MTok, cache_write 1h $20/MTok):

| Version | Sessions | TTL=1h | TTL=5m | 1h savings ($, Fable 5) | Total cost ($, Fable 5) | 1h savings / total |
|---|---|---|---|---|---|---|
| 2.1.215 | 28 | 19 | 7 | $39 | $2,098 | 1.9% |
| 2.1.218 | 17 | 0 | 16 | $179 | $1,249 | 14.3% |
| 2.1.219 | 29 | 0 | 26 | $6 | $182 | 3.4% |
| 2.1.220 | 83 | 0 | 81 | $1,511 | $9,121 | 16.6% |
| 2.1.221 | 4 | 0 | 4 | $120 | $872 | 13.8% |
| 2.1.222 | 3 | 0 | 3 | $80 | $500 | 16.0% |
| Total | 236 | | | $1,935 | $14,022 | 13.8% |

13.8% of total session cost across 2 weeks is attributable to the 1h→5m switch. This is not a fixed cost — it scales with session length and idle frequency. The 2.1.220 row alone (83 sessions, 325 gap-5-to-60-min drops) shows the impact at scale.

Related issues (the symptom, not the cause):

  • #77001 — "Disproportionate subscription usage burn in long sessions: cache TTL expiry re-writes": Reports the symptom (5m TTL causes cache re-writes and usage burn) but doesn't identify that the 1h TTL was removed in 2.1.218. This issue provides that root cause.
  • #74075 — "Expose extended (1h) prompt-cache TTL for interactive sessions": Requests the 1h TTL as a feature, but the 1h TTL was already in use and was silently removed. This issue reports the removal as a regression.
  • #81967 — "Prompt cache invalidation: tools array mutation and TTL downgrade during session": Reports intra-session TTL switching (1h ↔ 5m) on 2.1.220. This issue reports that on 2.1.218+, the 1h TTL is gone entirely — not an intra-session switch, but a complete removal.
  • #74149 — "ScheduleWakeup tool description claims '5-minute TTL' but subscription main sessions use 1-hour TTL": Documents the 2.1.215-era behavior (371/371 records on 1h TTL). This issue reports that the 2.1.218+ behavior contradicts that — the 1h TTL is no longer used.

Script: The drop-detection and cost-estimation script (cache-forensics-scan.py) is available on request.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

View original on GitHub ↗

3 Comments

dixit-ty-chetan · 2 months ago

On Bedrock hitting this: ENABLE_PROMPT_CACHING_1H=1 in your env restores 1-hour TTL on 2.1.223.

Add to ~/.claude/settings.json:

"env": {
"ENABLE_PROMPT_CACHING_1H": "1"
}

Confirmed working on AWS Bedrock + claude-opus-4-6 over a 58-min session with 6-14 min idle gaps — cache reads grew (787k → 1.1m), writes stayed flat (~402-403k), no re-caching after pauses.

This env var has existed since 2.1.108 but the default seems to have changed to 5m in 2.1.218 as reported here. The opt-in still works.

Refer: #74075 for more details

carrotRakko · 1 month ago

Update, three weeks later (2.1.220 → 2.1.247):

The setting shipped. As of v2.1.242+, the promptCacheTtl / subagentPromptCacheTtl settings (and CLAUDE_CODE_PROMPT_CACHE_TTL env vars) let API-key and cloud-provider users pin the TTL, and the prompt-caching docs now document the default matrix: the main conversation gets 1h on a Claude subscription within plan usage, 5m otherwise.

Measured in the same fleet as the original report (2026-08-06..27, 105 main + 265 subagent sessions):

  • Still 5m-only on every request through 2.1.247 by default. Our sessions authenticate with ANTHROPIC_AUTH_TOKEN (a gateway injects a subscription OAuth token), which the client buckets as "API key" — so setups like this silently miss the subscription 1h default, even though the server accepts 1h for the same token (verified: with promptCacheTtl: "1h", cache_creation lands in ephemeral_1h_input_tokens, and a 25-minute-idle probe read the cache back instead of rewriting).
  • Refining the original 13.8% estimate with the 2× 1h write premium accounted: net = 0.75×W − 1.9×S (W = total cache-write tokens, S = re-written cached tokens on 5–60 min gaps; break-even at S/W = 39.5%). Our fleet measures S/W = 67.3% → net saving ≈ 9.1% of total cost. Still clearly worth 1h for interactive main sessions.
  • Subagent bucket: S/W = 0–34.5% in our data, below break-even — the 5m subagent default matches measurement.

So for anyone landing here: "promptCacheTtl": "1h" in settings.json resolves the cost regression on 2.1.242+. What remains is the detection gap: a subscription token supplied via ANTHROPIC_AUTH_TOKEN gets the API-key default (5m) rather than the subscription default (1h).

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

edubraqd · 29 days ago

Confirming the "detection gap" reading rather than a regression, from a plain subscription login (no ANTHROPIC_AUTH_TOKEN, no gateway, Windows, Claude Code 2.1.156 → 2.1.272, 674 local sessions, usage deduplicated by message.id):

  • Main conversation: 159,724 cache writes in the 1h bucket, 16 in the 5m bucket (all 16 in one session in July).
  • Per version, main thread, versions with ≥ 200 calls: 1h = 100.0% on all 29 versions, including 2.1.219 (11,557 calls), 2.1.222, 2.1.260 (11,741) and 2.1.272. Nothing changed at 2.1.218.
  • Subagents: 92,525 writes, all 5m — matching the docs matrix and your subagent bucket.

So the default did not move to 5m for subscription sessions; what you found (a subscription token supplied as an API key gets the API-key default) is the whole effect here. For anyone else landing on this issue with 5m-only transcripts on a subscription: besides the auth path, DISABLE_TELEMETRY / CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC (#45381) and being in usage overage also put you on 5m.

Method and per-version table: https://github.com/edubraqd/claude-context-forensics (tools/ttl.py, report/issues-2026-09-15.md §7.1).