Prompt caching works best when the early part of the request stays byte-stable across calls. A coding agent naturally fights that requirement: tool results change, files change, memory changes, and child tasks need different instructions. Claude Code performance code is therefore mostly about preserving shape.
stable prefix = system + tools + headers + earlier messages
dynamic tail = current user turn + new tool output
addCacheBreakpoints(messages)
-> place one cache_control marker
-> keep volatile blocks after the reusable prefix
content replacement / cache_edits
-> shorten future provider view
-> keep local transcript and recovery state separate
A single request goes through a small decision trace before it becomes cacheable work. The runtime starts with messages, tools, model options, beta headers, and replacement state. The provider adapter turns those into Anthropic request blocks. addCacheBreakpoints() then chooses where the one message-level cache_control marker can live, keeping volatile tool output and the current turn after the reusable prefix when possible. The provider reports cache-read and cache-write counters back in usage metadata, and cache-break detection turns those counters into a client-visible signal. This is a shape-level client contract; it does not claim how the provider internally indexes or recomputes KV-cache state.
1. The API sees cache markers on request blocks
At the provider boundary, Claude Code converts runtime messages and tools into Anthropic request parameters. Cache control can be attached to selected blocks so the provider can reuse stable prompt prefixes. The important part is placement. A cache marker after a volatile block is much less valuable.

The memory chapter becomes important here. Long-lived material has to be classified by prompt entrance before it can be reasoned about as cache material. CLAUDE.md and rules are not hidden system-prompt magic in the visible source; they are projected through prependUserContext() into an early meta user message. Auto-memory content can enter user context or relevant-memory attachments, while write/search policy comes from the memory prompt section. If the projected text is unchanged, it can remain part of the reusable prefix. If memory files, the auto-memory index, or other user-context text is reloaded with different content, the provider-visible prefix may need to be written again.
| Dynamic material | Source handling | Cache consequence |
|---|---|---|
| memory / user context | prependUserContext() puts it near the front of messages. |
Stable text can be reused; changed projection can break the prefix. |
| deferred tools | Delta attachment avoids prepending fresh tool text each turn. | Tool discovery does not churn the message prefix. |
| beta headers | Session-level latch keeps request shape stable. | Feature toggles do not quietly change cache identity mid-session. |
2. Forking tries to keep the parent prefix stable
The fork path described in the subagent article has a cache consequence. If the child request can reuse the parent system prompt, tools, and selected message prefix, it can add task-specific instructions near the suffix while keeping the expensive front stable.

3. Microcompact reduces volatile pressure
Large or frequently changing blocks can break cache usefulness even when the nominal cache setting is enabled. Microcompact gives the runtime a smaller pressure valve: reduce a troublesome segment without forcing a full compact of the whole conversation.

4. Replacement state has to be request-aware
Content replacement helps keep long tool outputs and file-related state manageable. But replacement also changes what the provider sees. The runtime must know whether replacement preserves the facts needed by the next turn and whether it changes cache-sensitive request layout.

5. Cache-break detection makes performance visible
Without explicit detection, cache misses look like the model simply got slower. Claude Code tracks cache-sensitive changes so developers can distinguish unavoidable new work from accidental prefix churn. That turns performance from folklore into a debuggable runtime property.

6. The invariant
Performance follows request shape. Memory projection, stable prefixes, careful fork suffixes, bounded tool results, microcompact, and replacement state are all different ways to protect that shape. Treating prompt cache as a boolean setting misses the engineering problem.
Sources
The source-code claims in this article are based on the public mirror and the linked official documentation. Server-side behavior and private feature-gate policy are treated only as client-visible request shape.