>_

Claude Code Prompt Caching: The One Rule Behind It

Robin||9 min
Last updated: August 30, 2026
claude-codeprompt-cachingoptimizationcontextcost
Claude Code Prompt Caching: The One Rule Behind It
Corrected 2026-08-30: the cache lifetime

This post used to say Claude Code's prompt cache expires after five minutes, so a coffee break costs you a rebuild. That is the Anthropic API default. Claude Code requests the longer one-hour lifetime for its main conversation on a Claude subscription within the plan's included usage. Measured across 63,880 billed API requests, 100% of my Claude Code cache writes were on the 1-hour tier and none on the 5-minute tier, so those writes billed at 2x base input rather than 1.25x. Seven places in this post carried the wrong version, two of them inside the FAQ structured data where a body edit would not have reached them, and one of them a cost claim that did not mention a lifetime at all and so survived the first sweep. All seven are now fixed. The measurement is in what a long CLAUDE.md actually costs.

Why Anthropic Treats Cache Misses Like Outages

The Claude Code team monitors prompt cache hit rate like infrastructure uptime. If it drops too low, they open an incident. Not a bug ticket - an incident.

That surprised me. But once I understood why, a dozen confusing Claude Code behaviors clicked into place. Why CLAUDE.md loads before your conversation. Why plan mode is a tool call. Why /clear feels expensive. Every single one traces back to one constraint: prompt caching.

Anthropic's prompt caching documentation explains the API-level mechanics. This post goes deeper - into how those mechanics shape the tool you use every day.

How Prompt Caching Actually Works

Prompt caching works by prefix matching. Claude can cache a prefix of the conversation and reuse it on the next request - but only if that prefix is byte-for-byte identical. Change one character early in the prompt and the entire cache after that point is invalidated.

That one rule drives every UX decision in Claude Code.

Prefix Matching in Practice

If static content sits at the front of the prompt and dynamic content sits at the back, the static part stays cached across requests. If you flip that order - dynamic first, static after - you rebuild the cache on every message.

Same tokens. Wildly different cost.

A cache entry has a lifetime, and the lifetime sets the write price. The API default is a 5-minute TTL (time to live) at 1.25x the base input rate; a 1-hour TTL is available at 2x.

On a Claude subscription within your plan's included usage, Claude Code does not use the API default for its main conversation. Measured on 2026-08-30 across 63,880 billed API requests from 30 July to 29 August 2026, with no TTL setting configured on my side, every single cache write was on the 1-hour tier and the 5-minute tier was exactly zero. Since 10 September my subagent writes go to the five-minute tier, as the docs below describe. Unless you choose a TTL yourself, Claude Code requests the one-hour TTL only on a Claude subscription within your plan's included usage, for the main conversation plus a small set of helper requests. With an API key, a cloud provider or usage credits the main conversation gets five minutes, and requests outside the main conversation, such as subagents and compaction, default to five minutes. So on a subscription within plan usage a coffee break does not cost the main conversation a rebuild, and its cache writes bill at 2x rather than 1.25x. The full measurement is in what a long CLAUDE.md actually costs.

From Claude Code v2.1.242 the lifetime is configurable through the promptCacheTtl and subagentPromptCacheTtl settings, or the CLAUDE_CODE_PROMPT_CACHE_TTL and CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL environment variables, so the 1-hour tier is a default rather than a property of the tool. On an API key or a cloud provider, setting promptCacheTtl to 1h gives the main conversation the one-hour cache. If you set it to five minutes, the five-minute behaviour below applies to you again.

The Numbers That Matter

MetricValueSource
Cache write cost25% more than base input tokens on the 5-minute TTL, 100% more on the 1-hour TTLAnthropic docs
Cache read cost90% discount vs uncached input on most models (95% on Opus 5.5, 97.5% on Fable 5.1 and Mythos 5.1)Anthropic docs
Cache TTL5 minutes by default on the API, 1 hour available (Claude Code's default depends on how you are billed, see above)Anthropic docs
Minimum cacheable prefixVaries by model, see belowAnthropic docs

The minimum cacheable prefix is per-model, and you cannot infer it from how new or how capable the model is. It falls steadily across the Opus line, and then the same-generation pair breaks any rule you might draw from that: Sonnet 4.5 sits at 1,024 and Haiku 4.5 at 4,096, four times apart. Look it up per model rather than reasoning about it. Below the minimum, nothing caches and you get no error: cache_creation_input_tokens simply comes back as 0. Verified against Anthropic's documentation on 2026-08-15:

ModelMinimum prefix
Opus 5, Fable 5512 tokens
Opus 4.8, Sonnet 5, Sonnet 4.6, Sonnet 4.51,024 tokens
Opus 4.72,048 tokens
Opus 4.6, Opus 4.5, Haiku 4.54,096 tokens

Haiku 4.5 is the trap: at 4,096 it needs an eight times longer prefix than Opus 5 does, and four times what its own generation-mate Sonnet 4.5 needs. A 3K-token prompt caches on Opus 5 and Sonnet 5 and silently will not cache on Haiku 4.5 - which is exactly the model you reached for to save money.

On a model with the standard 90% discount on cached reads, the difference between a cached and uncached session is dramatic. A 100K-token context with 80% cache hit rate costs roughly 3.6x less per request than the same context with 0% hits: 80K tokens at 0.1x plus 20K tokens at 1x is 28K token-equivalents against 100K.

The Prompt Assembly Order

Claude Code assembles your prompt in a very specific order. This is not arbitrary - it is deliberately structured so the most stable content sits earliest in the prefix.

Claude Code Prompt Order (Static Before Dynamic)
Conversation MessagesChanges every turn - always dynamic
CLAUDE.md + Session ContextCached after first load
Static System Prompt + ToolsCached across the entire session

Layer 1: System Prompt and Tools

The system prompt and all tool definitions sit at the very front. These are identical across requests within a session, so they cache on the first message and stay cached. This is why MCP tool search defers tool schemas instead of loading them all up front. Deferred tools are known by name only until something actually needs one, and the full schema arrives later in the conversation rather than being edited into the front of it. The prefix stays byte-identical, so the cache survives.

Layer 2: CLAUDE.md and Static Context

Your CLAUDE.md file, rules files, and any static project context load next. These are more stable than your conversation but less stable than the system prompt (they can vary across projects). This layer caches after the first turn and stays cached for the session.

This is why changes to your project-root and user-level CLAUDE.md take effect only at the next /clear, /compact or restart - the file loaded at session start is part of the cached prefix.

Layer 3: Conversation Messages

Your actual messages sit at the back. They change every turn, so they are never cached as input (though they become part of the prefix for the next request). This is the dynamic layer where caching ends and full-price token processing begins.

Now watch what happens when something changes at layer two - a tool gets added, a model switches, or the system prompt gets edited. Everything below that point rebuilds from scratch.

prompt-cache-invalidation

That cascade is the cost nobody sees. One change at the wrong layer, and thousands of cached tokens become full-price tokens on every subsequent request.

What Breaks the Cache

Understanding what invalidates the cache is more useful than understanding what preserves it. Here are the four most common cache breakers:

1. Switching Models Mid-Session

Each model has its own cache. When you switch from Opus to Haiku mid-session, the Haiku model has no cached prefix - it builds from scratch at full token prices.

At high context volumes, this is counterintuitive: the first Haiku request after a switch can cost more than an Opus request at cached rates.

code
# What you think happens
Opus (expensive) → Haiku (cheap) = savings

# What actually happens at 100K of context (list prices, input only)
Opus 5.5 @ cache-read rate: ~$0.02/request
Haiku 4.5, first request after the switch (cache write): ~$0.13 to $0.20
Haiku 4.5 after that @ cache-read rate: ~$0.01/request

The docs say it plainly: after a model switch the next request gets no cache hits. A switch pays an entry fee of one full cache write, so it only pays off if you stay on the new model for many turns.

2. Adding or Removing Tools

Tools are part of the prefix. Adding a tool partway through invalidates everything cached after that point. This is why ToolSearch exists as an architecture pattern - deferred tool loading that keeps the prefix stable.

3. Using /clear Instead of Compaction

Cache-wise the two are close: both rebuild the conversation part of the cache. Compaction keeps the system prompt layer and reloads project context, which hits the cache only if CLAUDE.md and memory are unchanged. The difference is what you keep: compaction carries a summary of the work forward, and /clear starts the conversation from nothing.

4. Long Pauses Between Messages

This one is the opposite of what I originally wrote here, and it is worth being precise about who it applies to.

On a Claude subscription within your plan's included usage, a coffee break does not cost the main conversation a rebuild. Claude Code requests the 1-hour tier by default only on a subscription within your plan's included usage, and I measured 100% of cache writes on that tier with the 5-minute tier at zero, so a gap shorter than an hour leaves the cached prefix intact. Long thinking pauses are not a cost problem there. With an API key, a cloud provider, or once you are on usage credits, the main conversation defaults to five minutes, so a pause longer than that rebuilds the prefix unless you set promptCacheTtl to 1h.

If you are calling the API yourself, the 5-minute default does apply, and a pause longer than that rebuilds the prefix on your next request. The 1-hour TTL survives the gap and writes at 2x the base input price instead of 1.25x, so it pays off once enough reads follow, which for any real session is quickly.

Six Things This Changes About Your Workflow

The caching architecture has direct implications for how you should work:

CLAUDE.md loads before your conversation. Not because it is special - because it is more static than your messages. It gets cached after the first turn and stays cached for the session.

The <system-reminder> tags in your transcript are not noise. When Claude Code needs to inject updated instructions, it appends them to messages instead of modifying the system prompt. Modifying the system prompt would break the cached prefix. Those tags are saving cache hits on every subsequent request.

Plan mode is a tool call, not a mode swap. EnterPlanMode and ExitPlanMode appear as tool calls. If plan mode were a separate system prompt state, switching in and out would invalidate the cache. As a tool, it leaves the prefix intact.

Never add or remove tools mid-session. Tools are part of the prefix. Adding one partway through invalidates everything cached after that point. Plan your tool set upfront.

Model switching has an entry fee. After a switch the next request gets no cache hits and writes the whole context again. At 100K tokens that first Haiku 4.5 request costs more than a cached Opus 5.5 read; it pays off only if you stay on Haiku for many turns.

Long sessions benefit from cache stability. A 2-hour focused session with a warm cache is dramatically cheaper per-request than 12 short sessions that each rebuild from zero.

Cache-Safe Compaction vs /clear

This deserves its own section because the wrong choice here is the most expensive daily mistake.

/clear after every task
  • -Conversation cache starts over
  • -Session history gone
  • -No summary of the work carried forward
  • -System prompt layer still cached
Compaction over /clear
  • +System prompt layer reused
  • +Conversation rebuilt from a short summary
  • +Summary bridges old and new context
  • +Project context cached if CLAUDE.md and memory are unchanged

I used to /clear after every task. Now I only use it when I genuinely need a fresh context, not just a clean conversation view.

When to Actually Use /clear

  • Starting a completely unrelated task (different project, different domain)
  • The session has accumulated too much irrelevant context that compaction can't shrink
  • You suspect the model is stuck in a behavior loop and need a true reset

For everything else, let compaction handle it. The session management patterns I use are built around this principle.

SEVAlert level when cache hit rate drops
90%Discount on cached vs uncached input tokens (most models)

How to Audit Your Own Cache Behavior

If your Claude Code sessions feel inconsistent - sharp early, degraded later - check whether you are accidentally breaking the cached prefix.

Symptoms of Cache Degradation

  • Sessions that suddenly feel slower after a model switch or tool change
  • Unexpectedly high token usage reported in the billing dashboard
  • On the API with the 5-minute default, or in Claude Code on an API key, a cloud provider or usage credits, a slow first response after a gap longer than the TTL (not a symptom for the main conversation on a subscription within plan usage, which runs on the 1-hour tier)

Quick Self-Check

  1. Are you switching models mid-session? Stop. Pick one at the start.
  2. Are you using /clear between tasks? Switch to compaction.
  3. Are you adding tools mid-session? Plan your tool set upfront in your CLAUDE.md configuration.
  4. Are you calling the API directly with the default TTL? Then a break longer than five minutes rebuilds the prefix. The same holds for the main conversation in Claude Code on an API key, a cloud provider or usage credits. On a subscription within your plan's included usage the main conversation has the one-hour TTL, so breaks are not the thing to change there.
Quick audit for your sessions

If your Claude Code sessions feel inconsistent - sharp early, degraded later - check whether you are adding tools, switching models, or using /clear mid-session. Each of those makes the next request rebuild part of the cache.

Why This Architecture Exists

Prompt caching is not a nice-to-have. At the token volumes Claude Code sessions generate - especially with long CLAUDE.md files, large tool sets, and extended conversations - without caching the cost would make the tool impractical for daily use.

The architecture is a product constraint turned into a design principle. And once you see it, the entire tool becomes more legible:

  • The context management system I built is partly a cache optimization strategy in disguise - keeping stable content stable and dynamic content minimal.
  • The delegation system benefits too - sub-agents start with a small, focused prefix instead of inheriting a bloated 100K-token conversation. Less prefix, less cost, regardless of cache state.
  • Hooks preserve the prefix by design - they inject behavior through tool-use events, not system prompt modifications.

Every pattern I use connects back here.

Updated 2 October 2026: the cache lifetime and cache-read price statements now match the current Claude Code and pricing docs, which limit the one-hour default to the main conversation on a subscription within plan usage and list lower cache-read prices for Opus 5.5, Fable 5.1 and Mythos 5.1. The corpus result is now dated, because subagent writes moved to the five-minute tier on 10 September 2026. The model-switch example uses current Opus 5.5 and Haiku 4.5 prices, and the compaction and CLAUDE.md reload statements follow the docs.

This lives in primeline-ai/evolving-lite - the self-evolving Claude Code plugin. Free, MIT, no build step.

FAQ

What is Claude Code prompt caching and why does it matter?+
Prompt caching lets Claude reuse a computed prefix of your conversation across multiple requests, paying a fraction of the normal token cost on the cached portion. In Claude Code, the system is structured so your static configuration (system prompt, tools, CLAUDE.md) sits at the front of the prefix and gets cached. The more stable your session setup, the higher your cache hit rate, and the lower your per-message cost.
Why does switching models mid-session cost more?+
Each model has its own cache. When you switch from Opus to Haiku mid-session, the Haiku model has no cached prefix - it builds from scratch at full token prices. At high context volumes, the first Haiku request after a switch can cost more than an Opus request at cached rates. The advice is to choose your model at session start and stay with it.
What is the difference between /clear and compaction in Claude Code?+
/clear destroys the session and forces a full cache rebuild on the next request. Compaction summarizes the conversation but keeps the same system prompt, tools, and prefix structure - so the cached prefix survives. For long working sessions, compaction is almost always the better choice.
Why does plan mode appear as a tool call instead of a separate mode?+
Tools are part of the cached prefix, so EnterPlanMode and ExitPlanMode as tool calls leave the prefix intact. If plan mode were a separate system prompt state, switching in and out would invalidate the cached prefix on every use. The tool design is a caching decision.
How do system-reminder tags relate to prompt caching?+
When Claude Code needs to inject updated context or instructions mid-session, it appends them to messages rather than modifying the system prompt. Modifying the system prompt would change the static prefix and invalidate the cache. System-reminder tags let Claude inject updates while keeping the prefix stable and the cache hit rate high.
How long does the Claude Code prompt cache last?+
Unless you choose a TTL yourself, Claude Code requests the 1-hour TTL (time to live) for its main conversation only on a Claude subscription within your plan's included usage (https://code.claude.com/docs/en/prompt-caching#which-ttl-each-request-gets). With an API key, a cloud provider or usage credits the main conversation gets the 5-minute API default, and requests outside the main conversation, such as subagents and compaction, default to five minutes. In my measurement across 63,880 billed API requests in August 2026, 100% of cache writes were on the 1-hour tier and none on the 5-minute tier, so on that tier a short break does not expire the cached prefix. The 1-hour tier bills cache writes at 2x base input rather than 1.25x. From Claude Code v2.1.242 the lifetime is configurable via the promptCacheTtl and subagentPromptCacheTtl settings or the CLAUDE_CODE_PROMPT_CACHE_TTL and CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL environment variables, so this is a default rather than a fixed property. If you call the Anthropic API directly, the 5-minute TTL is the default and a gap longer than that does rebuild the prefix.
What is the cost difference between cached and uncached Claude Code requests?+
On most models, cached input tokens cost 90% less than uncached input tokens: a cache read is 0.1x the base input price, or 0.05x on Opus 5.5 and 0.025x on Fable 5.1 and Mythos 5.1. The cache write costs more than base input, and how much depends on the tier: 1.25x on the API's 5-minute default, 2x on the 1-hour tier, which Claude Code requests for the main conversation on a Claude subscription within your plan's included usage. At the standard 0.1x read price, over a long session the reads dominate and the saving approaches 10x, but in my own measurements the median Claude Code session has a hit rate of around 86% rather than 96%, and at that rate cache writes carry about three quarters of the cache-input cost.
How do I know if my Claude Code cache is working properly?+
Read message.usage.cache_read_input_tokens in your session transcripts under ~/.claude/projects. If it is zero across repeated turns, something is breaking the cached prefix. The usual causes are switching models mid-session, adding tools mid-session, and using /clear instead of compaction. On a Claude subscription within your plan's included usage, the main conversation runs on the 1-hour cache tier, so only a break longer than an hour expires it. On an API key, a cloud provider or usage credits the main conversation defaults to five minutes, so a longer break can be a cause.

>_ Get the free Claude Code guide

>_ No spam. Unsubscribe anytime.

>_ Related