Skip to content

Prompt Caching

Qin Yu, 7 Sep 2026


Prompt caching is the largest term in the cost of an interactive agent session, and the one most people never look at. It also sets the real price of two things this guide recommends elsewhere: switching models and tuning effort.

Most of your input tokens are cache reads, not new context.

TL;DR: The model is stateless, so the harness re-sends the whole conversation every turn; a cache read costs about a tenth of a fresh input token, which is what makes that affordable. The match is on an exact prefix, so appending is cheap and changing anything near the front is expensive. Pick your model and effort level at the start of a session, then leave them alone.

Why Caching Dominates Agent Token Cost

An LLM remembers nothing between requests. Every turn, the harness re-sends the system prompt, your project instructions, the entire prior conversation, every tool result so far, and your new message. A turn in which the agent makes five tool calls is six requests, each carrying everything before it.

So the total input for a session is roughly:

\[ \text{total input tokens} \approx \text{number of requests} \times \text{mean context size} \]

It grows fast, which is why a one-line follow-up in a session open all day still costs the whole conversation. Caching stops that being ruinous: the API recognises what it has already processed and bills the re-read at roughly 10% of the base input price.

The difference is an order of magnitude on the same work. Fifty requests over a conversation averaging 200k tokens is 10M input tokens; on Claude Opus 5 that is about $50 uncached and about $5 from cache. Nothing about the transcript changed — only whether the prefix matched.

It is also why measurements of agent token spend are dominated by cache reads rather than by any individual file read. The question is not how many tokens are in your context, but how many of them are cache reads.

How the Cache Works: Prefix Matching

The cache key is the exact byte sequence of the request up to a cache breakpoint, so a single changed byte at position N invalidates everything from N onward. There is no per-file or per-segment caching — you cannot cache a file read and reuse it in another conversation.

Harnesses therefore order each request so that the least volatile content comes first:

Layer Contains Changes when
1. System prompt Core instructions, tool definitions, output style The loaded tool set changes, or the harness is upgraded
2. Project context CLAUDE.md / AGENTS.md, memory, unscoped rules Session start, /clear, or compaction
3. Conversation Your messages, agent responses, tool results Every turn

A change invalidates its own layer and everything after it, never anything before it:

flowchart LR
    A["Change in layer 1<br/>system prompt, tool definitions,<br/>model, effort"] --> A1["Full rebuild:<br/>nothing is reused"]
    B["Change in layer 2<br/>new session, compaction"] --> B1["System prompt reused,<br/>rest rebuilt"]
    C["Change in layer 3<br/>an ordinary turn"] --> C1["Everything before<br/>your new turn reused"]

So append-only work is cheap and rewriting the front of the request is expensive. Plan mode, skills, and slash commands append to the conversation, costing their own tokens and nothing more. A model switch rewrites the whole key, costing the entire conversation again.

If you build your own prompts, mind the minimum: a prefix below it fails to cache silently, with no error and no cache tokens reported. The minimum is not monotonic across generations — 512 tokens on Opus 5 and the Fable 5 family, 1,024 on Opus 4.8 and Sonnet 5, 4,096 on Opus 4.6 and Haiku 4.5. A 3k-token prefix caches on Opus 5 and silently does not on Haiku 4.5.

Cache Lifetime

Cache entries expire after a period of inactivity. Two properties of the clock are easy to get wrong:

  • Every cache read resets the timer, for free. A session stays warm indefinitely as long as you keep working within the TTL.
  • The lifetime is measured from the start of the request, not the end of the response. Generation counts against it, so a four-minute turn leaves about one minute to start the next request before a five-minute entry expires.

The Claude API offers a five-minute TTL by default and a one-hour TTL that costs more to write. Which one you actually get in Claude Code depends on how you are billed:

Request bucket Claude subscription, within plan usage Usage credits, API key, or cloud provider
Main conversation One hour Five minutes
Sub-agents, workflows, forks, compaction Five minutes Five minutes

Two consequences. Cross into usage credits and the main conversation silently drops from a one-hour cache to a five-minute one — exactly when you start paying per token. And sub-agents never get the hour by default, so one that pauses six minutes between turns pays full price to resume.

Both are configurable: promptCacheTtl (or CLAUDE_CODE_PROMPT_CACHE_TTL) for the main conversation and subagentPromptCacheTtl for everything else, each accepting 5m or 1h.

Whether the longer TTL pays for itself is arithmetic, not preference. A five-minute write costs 1.25× base input and a one-hour write costs 2×, against a read at 0.1×:

  • Under five minutes between requests — the default TTL is refreshed by every request and is strictly cheaper. The hour buys nothing and costs 2× on writes.
  • Five to sixty minutes — the only window where the one-hour TTL earns its premium. This is the "I went to a meeting and came back to the same task" case.
  • Over an hour — neither helps. Accept the cold turn, or start clean.

Dated section — last checked 7 September 2026

The mechanism above is durable. The specific TTL defaults, per-model minimums, prices, and setting names change; the multipliers (1.25× / 2× / 0.1×) have been stable, but check the linked pricing and caching pages before acting on any number here.

What Breaks the Cache

These make the next request re-read some or all of the conversation at full price — one slower turn each, not a permanent penalty, but mid-task they add up.

Action Why
Switching model Caches are model-scoped; identical content, different cache
Changing effort level Effort is rendered into the prompt, so it is part of the cache key. The conversation layer always rebuilds; whether tools and system rebuild too is model-specific
Turning on fast mode Adds a header that is part of the cache key; costs once per conversation
Connecting or disconnecting an MCP server Only when its tools sit in the prefix rather than being deferred — including a stdio server that crashes and reconnects on its own
Enabling a plugin that provides MCP servers Same rule as the server itself; a plugin's skills, commands, agents, and hooks are cache-safe
Adding a bare tool name as a deny rule Removes a built-in tool definition from the system prompt
Compacting the conversation By design: the history is replaced with a summary that shares no prefix
Accumulating many images Old images are evicted when a request would exceed the image limit, rewriting the messages that held them
Upgrading the harness New system prompt or tool definitions; applies on next launch, and resuming a long session after an upgrade is often the single most expensive request you will send

And the safe ones, several of which people avoid unnecessarily:

Action Why it is safe
Editing files in your repository File contents enter context only when read; a change appends a notice rather than rewriting history
Editing CLAUDE.md mid-session Held in memory from session start — but note the edit also does not apply until /clear, compaction, or restart
Changing output style Same: cache-safe because it is fixed at session start, and equally does not apply until restart
Changing permission mode Does not touch the system prompt or tool definitions
Invoking a skill or slash command Injected as a message at the point of invocation
/recap Appends a summary instead of replacing history, unlike /compact
/rewind Truncates back to a prefix the cache already holds, so it hits an earlier entry
Spawning a sub-agent Appends the call and result to the parent; the parent's prefix is untouched

A useful asymmetry in that last pair: to abandon a path, /rewind is cache-cheap and /compact is not. Rewinding returns to bytes the cache already holds; compaction builds a prefix that has never existed.

Model and Effort Switching

Model Selection recommends routing by task shape and stepping effort down as the primary cost lever on the current generation. Both are correct as decisions made per workload or at the start of a session. Neither is a reason to flip settings mid-conversation:

  • Caches are model-scoped, with no escape hatch. Switching Opus to Sonnet mid-session to save money pays a full uncached rebuild at the new model's rate; on a large session that can cost more than the switch saves, and switching back pays a third time. Claude Code asks you to confirm a /model switch only while the cache is warm, and stops asking once it has expired and the switch is free.
  • Effort changes invalidate too, which is counter-intuitive until you see why. Effort is not an out-of-band knob like temperature: the effort and thinking configuration is rendered into the prompt, so changing it changes the bytes and the match fails from wherever that configuration sits. On Claude it always invalidates the conversation layer; whether tools and system go too depends on the model rendering the configuration ahead of them. Setting effort to the model's own default is a no-op.
  • The exceptions are narrow — check rather than assume. Each works as the prefix rule predicts, by moving the change after the cached content. Opus 5, Fable 5.1, and Mythos 5.1 take a per-message effort change on a role: "system" message inside messages, behind a beta flag, with no cache reset. In Claude Code, effort changes on Fable 5.1 keep the cache with an API key or a subscription, but not on Amazon Bedrock, Google Cloud's Agent Platform, or a Claude apps gateway. Elsewhere there is no tiering and so no partial survival — see Other Harnesses.
  • opusplan makes every plan-mode toggle a model switch, because it resolves to Opus in plan mode and Sonnet during execution.

To use a different model without paying twice, prefer isolation over switching: send cheap read-heavy work to a sub-agent with its own model, and keep the main conversation on one model at one effort level. That is the Advisor Strategy, cache-aware by construction.

The same logic covers any parameter rendered into the prompt. Pin thinking and effort per route rather than per request; tool_choice changes and added images are cheaper than they look, invalidating only the message layer.

Sub-agents, Forks, and Parallel Fan-out

Sub-agents and parallelism interact with caching in ways the token counts alone do not show.

  • A sub-agent cannot read its parent's cache. Its own system prompt and tool set make a different prefix, so its first request is uncached and it warms a cache of its own. That is the price of the isolation that makes sub-agents worth using — but one spawned for a two-turn task may never recoup its own cache write.
  • A fork does read the parent's cache, inheriting its system prompt, tools, and history exactly. For a cheap divergence rather than isolation, fork.
  • Parallel workers over the same prefix cannot share a cold cache. An entry becomes readable only once the first response starts streaming, so N simultaneous identical-prefix requests all pay full price. Claude Code mitigates this in workflow fan-outs by briefly holding all but the first agent.

This qualifies Orchestration Patterns: parallelism buys wall-clock time, not tokens. N workers each assembling a slightly different prompt over the same context write N entries and read none of each other's, so fewer lanes over a byte-identical prefix is often cheaper.

Measuring Your Own Cache Performance

Do not reason from first principles when the numbers are right there. Every API response reports cache_creation_input_tokens (written this turn, at the write premium) and cache_read_input_tokens (served from cache, at roughly a tenth). A high read-to-creation ratio means caching is working; creation staying high means something in your prefix keeps changing.

In Claude Code specifically:

  • /usage shows a Prompt cache (main) line after the first response — request count, share of input tokens served from cache, misses, whether the cache is warm right now, and the TTL in effect. From v2.1.260 it also names the likely cause of the last miss, such as likely cause: tool definitions changed. Requires v2.1.251 or later.
  • The plan usage breakdown in /usage flags cache misses as a behaviour when they account for 10% or more of recent usage, and attributes usage to individual skills, sub-agents, plugins, and MCP servers.
  • A status line script can read the same figures live from the prompt_cache object (hit_ratio, misses, warm, ttl, last_miss_cause, and others).
  • Session logs at ~/.claude/projects/<project>/<session-id>.jsonl record the raw per-turn fields — what you want for before/after comparisons of a configuration change.
  • OpenTelemetry export reports cache read and creation tokens per user and session for organisation-wide visibility.

Calling an API directly and seeing zero cache reads across repeated identical-prefix requests means a silent invalidator in your prompt assembly. Usual suspects: a timestamp or UUID in the system prompt, JSON serialised without sorted keys, a conditional system section, or a per-user tool list. Diff two consecutive request bodies — the first divergence inside the overlap is the culprit.

Other Harnesses

Caching is automatic on supported models — no markers to place. For GPT-5.6 and later the cache lives at least 30 minutes after the most recent write or reuse, far more forgiving than a five-minute default; older models used a shorter in-memory window with an opt-in longer retention.

Cached input tokens cost 0.1× the uncached rate, and cache writes on GPT-5.6 and later cost 1.25×. The minimum cacheable prefix is 1,024 tokens on GPT-5.6 and later, 2,048 on older models.

The invalidation rules are the familiar ones plus a few extra parameters: the model, tool definitions and their ordering, parallel_tool_calls, output format, reasoning effort, response verbosity, and compaction settings are all part of the rendered prefix.

There is no layered cache here: OpenAI matches one longest prefix over the whole rendered context, so nothing survives a change the way Claude's tools and system tiers can — any of those parameters breaks the match outright. The only documented escape hatch is a configuration_update input item, which changes effort between responses while leaving request-level reasoning.effort untouched, on GPT-6 Astra alone. The lesson transfers: pick a sibling model and an effort level per workload, not per request.

Copilot exposes no cache-control knobs, but GitHub documents the invalidators, and the list is familiar: switching models mid-session, and changing the reasoning effort level, the context size, or the set of enabled tools and MCP servers during a session. GitHub calls the result a rebuild from scratch, not a partial loss, and advises configuring all of it before you start.

Lifetimes are far more forgiving than on the Claude API — 24 hours for OpenAI models, one hour for most others — so returning to yesterday's session costs much less here than in a five-minute-TTL setup.

What you do not get is measurement: no per-request cache read is surfaced, so the habits have to be followed on trust. Auto mode can also change the model underneath you, which is one more reason to treat a long session as the unit of work.

Self-hosted servers do prefix caching too, but there is no clock at all — the opposite failure mode from a five-minute TTL, and worth knowing if you run models on your institution's GPU infrastructure.

vLLM hashes KV blocks and keeps them until memory pressure forces eviction, LRU among blocks with no active references; SGLang's RadixCache does the same over tree nodes, evicting the coldest subtree. A prefix survives as long as the server has spare KV cache and nobody else needs it: hours on an idle server, seconds on a busy shared one. Lifetime is a function of your neighbours, not a documented TTL.

Two implications. Sharing a prefix across users and jobs matters more here than on a hosted API, since every hit is prefill you do not pay GPU time for. And the benefit appears as latency and throughput rather than a line on a bill, so measure time-to-first-token and requests per second, not tokens.

Practical Rules

  • Pick model and effort at the top of a session, and leave them alone until the task changes.
  • Keep one task per session. The cache and the context window want the same thing.
  • /rewind to abandon a path; /compact only at a natural break. Compaction's cost is unavoidable, but you choose when to pay it, and it is cheapest while the cache is warm.
  • Prefer sub-agents over model switching when part of the work wants a cheaper model.
  • Edit CLAUDE.md and settings between sessions, not during them — mid-session edits are cache-safe precisely because they do not take effect.
  • Set promptCacheTtl to 1h if you work in long sessions with meeting-length gaps on an API key or cloud provider, or on usage credits.
  • Check your own hit ratio before optimising anything else. /usage tells you in one line whether caching is the problem.
  • For API workflows, put invariant content first and everything volatile after the last breakpoint, then verify with the usage fields rather than assuming.
References