Skip to content

How prompt caching shapes Claude Code's speed and bill: prefix matching, invalidation triggers, and hit rate

Aug 26, 2026 1 min
TL;DR Claude Code's prompt caching works by exact prefix matching: a cache read bills at roughly 10% of the standard input rate, but switching models, changing effort, enabling fast mode, toggling MCP servers, or denying an entire tool forces the next turn to reprocess everything. The TTL defaults to five minutes; the main conversation and a few helper requests on a subscription get one hour.
Table of Contents
  1. Why sessions get faster and cheaper the longer they run
  2. Why the turn after switching models is so slow
  3. Why CLAUDE.md edits don't apply mid-session
  4. What /compact actually costs
  5. How to check your own cache hit rate
  6. What breaks the cache, and what doesn't
  7. Takeaways
  8. References
  9. Changelog

🌏 中文版

After using Claude Code for a while, you've probably noticed a few things: responses get faster as a session goes on without the bill growing proportionally; one day you run /model and that single turn takes noticeably longer; you edit CLAUDE.md mid-session and Claude acts like it never saw it. All of these have the same answer — prompt caching. This post maps each confusion onto the mechanism, following the official documentation.

Why sessions get faster and cheaper the longer they run

Every turn in Claude Code re-sends the full context: the system prompt, your project context, every prior message and tool result, with new content appended at the end. The model itself remembers nothing between requests. If everything were reprocessed from scratch each turn, long sessions would be unusably slow.

The API's answer is prefix matching: it compares the start of each request against content it recently processed. Anything exactly identical is read from cache — the re-read is billed at the cached token rate, roughly 10% of the standard input rate — and only the appended tail is fully processed. Since most of each request matches the previous one, the hit rate naturally climbs while you keep working. That's the "faster the longer you use it" effect.

Claude Code deliberately orders each request into three layers, least-changed first:

LayerContentChanges when
System promptCore instructions, tool definitions, output styleThe tool set changes, or Claude Code is upgraded
Project contextCLAUDE.md, auto memory, unscoped rulesSession starts, or after /clear / /compact
ConversationYour messages, responses, tool resultsEvery turn

Matching requires an exact match, so a change anywhere in the prefix recomputes everything after it. There is no per-file or per-segment caching.

Why the turn after switching models is so slow

The model is part of the cache key: each model has its own cache. The first request after /model reads the entire conversation history with no cache hits — even though the content is identical. That's the slow turn. Afterward the new prefix is written to cache and things return to normal.

Effort level and fast mode's request header are part of the cache key too. Also note that the opusplan setting resolves to Opus during plan mode and Sonnet during execution, so every toggle in and out of plan mode is a model switch that starts a fresh cache.

Why CLAUDE.md edits don't apply mid-session

CLAUDE.md files are read once at session start and held in memory. Editing them mid-session doesn't invalidate the cache, but the edit also doesn't apply — Claude keeps working with the version loaded at startup. New content loads on the next /clear, /compact, or restart.

This isn't a bug; it's a direct consequence of the cache structure. CLAUDE.md sits in the project-context layer. If it were re-read every turn, the prefix would keep shifting and the entire conversation's cache would be invalidated. Loading it once at the start trades delayed updates for a stable cache across the whole session.

One exception: nested CLAUDE.md files in subdirectories and rules with paths: frontmatter load later, when Claude first reads a matching file — editing them before that happens does take effect.

What /compact actually costs

Compaction replaces your message history with a summary, so the conversation layer necessarily invalidates — the new history shares no prefix with the old one. The system prompt layer survives, and project context is reloaded from disk, hitting the cache only if CLAUDE.md and memory are unchanged since the session started.

Producing the summary is itself an API request. While the cache is warm, that request reads your cached prefix, so a mid-session /compact costs far less than the context size suggests. But if you step away longer than the cache lifetime before compacting, the full history gets reprocessed as uncached input — which is why running /compact right after resuming an old session costs the most.

For comparison, /rewind is much friendlier: it truncates back to a prefix that was already cached, so the next request hits the earlier cache entry instead of building a new one.

How to check your own cache hit rate

The API reports two token counts on every response:

FieldMeaning
cache_creation_input_tokensTokens written to cache this turn, billed at the write rate
cache_read_input_tokensTokens served from cache this turn, at roughly 10% of the standard input rate

The most direct way to watch them live is a statusline script reading the current_usage object. A high read-to-creation ratio means caching is working well; if creation stays high turn after turn, something keeps changing your prefix. For organization-wide visibility, the OpenTelemetry exporter reports both counts per user and session.

On cache lifetime: there are two TTLs, five minutes and one hour, and every cache hit resets the timer. By default the main conversation gets one hour on a subscription within included usage, and a small set of Anthropic-controlled server-side helper requests also gets one hour; everything else gets five minutes. Past your usage limit, the main conversation drops back to five minutes. From v2.1.242 onward you can control it with the promptCacheTtl setting or the CLAUDE_CODE_PROMPT_CACHE_TTL environment variable.

What breaks the cache, and what doesn't

Actions that make the next turn partially or fully reprocess: switching models, changing effort level, turning on fast mode, connecting or disconnecting an MCP server (when its tools aren't deferred), enabling or disabling plugins that provide MCP servers or code intelligence, adding a deny rule for a bare tool name, and upgrading Claude Code. Some MCP disconnects aren't even your doing — a stdio process exiting, an HTTP session expiring, or an automatic reconnection all trigger it.

Actions that keep the cache: editing files in your repo (file contents enter context only when read; changes append a system-reminder), invoking skills and slash commands (instructions append as messages), changing permission modes, and running /recap.

One easily missed scope limit: the cache is effectively scoped to one machine and directory. The system prompt embeds the working directory, platform, shell, and more, so two worktrees of the same repository build different prefixes and never share cache.

Takeaways

Condensed into one operating principle: pick your model and effort at the start of a session, save /compact for natural breaks between tasks, and avoid touching settings that shift the prefix mid-task — the hit rate takes care of itself. For how the context window itself is managed, see the earlier post in this series; for the full CLAUDE.md and memory rules, see the .claude directory guide.

References

Changelog

  • 2026-08-26: Initial version, based on the official prompt caching documentation as of August 2026.