Todd Mercer

If claude -p writes your prompt cache under the 1-hour TTL but an ordinary interactive session on the same account, machine, and model writes ephemeral_5m from the first turn, you are not imagining a billing change. Reporters traced the cause to a cache-keepalive-2026-09-03 beta flag that the interactive client sends on every request; when the server sees that beta, it records the write as 5-minute even though the client's own request still asks for ttl: "1h". The confirmed fix available today is to set promptCacheTtl to 1h yourself, which stops the client from sending that beta at all.
Next action: install Aident Loadout once, then run a bounded Code Interpreter check that reads your own session transcript and reports the cache bucket each turn actually used, before you decide whether to pin the TTL:
Preflight the exact Action, then run a read-only check such as jq -c 'select(.type=="assistant" and .message.usage.cache_creation) | [.timestamp, .message.usage.cache_creation]' ~/.claude/projects/<project>/<session>.jsonl against one of your own transcripts. That confirms what your sessions are actually doing; use the setting below to change it.
The Exact Symptom
GitHub issue anthropics/claude-code#101685, opened October 13, 2026, is still open as of October 22, 2026, with reports from at least ten independent accounts across macOS, Linux, and WSL2, on Claude Code versions from 2.1.296 through 2.1.304:
A fresh interactive session writes every main-thread cache entry as
ephemeral_5m_input_tokens, withephemeral_1h_input_tokensat 0, from its very first turn.claude -pruns on the same account, same machine, same model, run minutes apart, writeephemeral_1hthe whole time.The TTL looks fixed at session start: no session in any report changed bucket partway through.
It is not an overage problem. Reporters checked
/usage, theanthropic-ratelimit-unified-overage-statusresponse header, andcachedExtraUsageDisabledReasonin~/.claude.json, and confirmed the affected accounts were within their plan's included usage, not drawing on usage credits.The onset date is per-account, not per-version: different reporters saw the same client version (2.1.296 through 2.1.304) behave correctly for days before switching to 5-minute writes, which points at a server-side flag rollout rather than a code change in a specific release.
If you also see queued tool calls or background work getting cut off mid-run, that is a separate failure mode; see our background task SIGTERM guide for that symptom instead.
The Confirmed Root Cause
A reporter in the thread intercepted their own client's API traffic with a local proxy and isolated the variable on October 15, 2026:
Run | Client sends |
| Server writes |
|---|---|---|---|
Default interactive session (×3) |
| Yes |
|
Same session, beta header removed in flight (×2) |
| No |
|
Interactive session with |
| No |
|
|
| Never sent by |
|
The client still requests the one-hour TTL in every case. When the request also carries the cache-keepalive-2026-09-03 beta header, the server records the write as five minutes regardless of what the client asked for. That single table explains every pattern in the thread: -p never sends the beta, so it is unaffected; setting promptCacheTtl explicitly makes the client stop sending the beta, so it also becomes unaffected; and the beta appears to roll out per account on a remote flag, which is why onset dates differ by reporter rather than by client version.
A second, related symptom in the same thread: the client's idle-keepalive mechanism sends POST /v1/messages/cache_touch roughly every 30 seconds while a session is idle. At least one reporter found those touches did not reliably keep the conversation cache alive past about 11 minutes in a controlled test, so even accounts not hit by the main bug can see unexpected cache misses after a mid-length pause. Anthropic has not published a statement on either behavior as of this writing; treat both as open and re-check the issue before assuming they are fixed.
The Workaround: Pin the TTL Yourself
Every report that tried it confirms the same fix. Add this to ~/.claude/settings.json (merge it into your existing settings if the file already has other keys):
Or set the equivalent environment variable if you prefer not to edit the settings file:
Notes on this exact fix:
It takes effect on a session's next request, without a restart. Multiple reporters confirmed a running session switched from
ephemeral_5mtoephemeral_1hon the very next turn after the setting was added.promptCacheTtlonly accepts5mor1h; Claude Code ignores any other value per the prompt-caching reference.This setting controls the main conversation bucket only. A separate
subagentPromptCacheTtlsetting andCLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTLenvironment variable control subagent, workflow, and compaction requests, which default to 5 minutes regardless of this bug.Setting an explicit TTL is also the one documented way to get the 1-hour cache on an API key or cloud-provider account, independent of this specific regression, so it is a safe default to carry forward even after the keepalive-beta issue is resolved upstream.
If you are optimizing cost or context size more broadly, see our guide to the context meter showing the wrong window size, which covers a different but related usage-accounting discrepancy.
Verify the Fix on Your Own Account
Do not take the workaround on faith; check your own transcripts, since the bug is server-flag-based and may not affect every account the same way.
Start a new interactive session and send one short turn.
Find your current project's session file under
~/.claude/projects/<project>/(the most recently modified.jsonl).Run:
If the third field (1h tokens) is 0 and the fourth field (5m tokens) is nonzero, you are hitting this bug. Add
promptCacheTtl: "1h"to~/.claude/settings.jsonand repeat the check on your next turn; the 1h field should now be nonzero.If you are on a Claude subscription and still see 5-minute writes after pinning
promptCacheTtl, confirm you are not in usage overage (/usage) before assuming the setting failed, since overage still forces 5-minute writes by design even with an explicit setting.
Recheck issue #101685 periodically; a fix that stops sending the beta header for unaffected accounts, or stops the server from downgrading the TTL when the beta is present, would make the explicit promptCacheTtl setting unnecessary again, though it remains harmless to leave set.
Sources and Method
anthropics/claude-codeissue #101685, opened October 13, 2026, open with reports through October 20, 2026, including the October 15, 2026 proxy-intercept root-cause finding reproduced in the table above.Claude Code prompt-caching reference, inspected October 22, 2026, for the
promptCacheTtlsetting,CLAUDE_CODE_PROMPT_CACHE_TTLenvironment variable, and subagent-bucket defaults.Related: issue #102338, a status-line symptom report of the same keepalive-beta behavior, cited in the main thread as independent corroboration.
About the author

Todd Mercer
Todd Mercer is a senior engineer with more than 10 years of experience working on social media platforms and large-scale ordering systems. He graduated from the University of Illinois Urbana-Champaign in computer science. At Aident, he covers technical issues, developer tools, and technology topics.



The one tool
for every tool
your agent needs.
Give any AI agent real capabilities in seconds. Connect 27,000+ tools once, skip the setup headache, and let your agents execute.


