Request and Cache
Each time the model must answer, Claude Code builds one request to the Messages API. The request holds the tool list, the system prompt, and the whole conversation so far. The API can reuse the start of a request it has seen before. That reuse is the prompt cache. What you change in the request decides what the cache can reuse, so it decides speed and cost.
At a Glance
| Question | Answer |
|---|---|
| Can you use it? | ✅ Yes. Every model call uses it. |
| Can you change it? | ✅ Yes. Change the cache lifetime, add body fields, or turn caching off. |
| Can you turn it on or off? | DISABLE_, and the per-family variants. |
| Where does it live? | Built in memory for each call. A record is saved in the transcript as api- lines. |
| Status | Documented Undocumented |
Parts of a Request
The API reads the parts in this order: tools, then system, then messages. A change in an early part makes the later parts miss the cache. Source: How Claude Code Uses Prompt Caching.
| Part | Status | Content | Changes when |
|---|---|---|---|
tools | Documented | The tool definitions. MCP tools are deferred by default, so only their names go in. | The set of loaded tools changes. |
system | Documented | The attribution line, the identity line, and the system prompt. | The model, the output style, or the prompt flags change. |
messages | Documented | The first user message with project context (CLAUDE., auto memory, unscoped rules), then the conversation. | Every turn. |
Project context changes at session start, at /clear, and at /compact.
Body Fields
The field list comes from the official docs and from an api-request line that version 2.1.304 wrote to a local transcript.
| Field | Status | Content |
|---|---|---|
model | Documented | The model ID. |
max_ | Documented | The output limit. CLAUDE_ can change it up to the model cap. |
thinking | Documented | The thinking mode, such as {"type":. |
output_ | Documented | The effort level, the format of structured output, and task_. See Gateway Compatibility Guide in the official docs. |
context_ | Documented | Edits that clear old thinking or old tool results. |
betas | Documented | The list of beta values, sent in the anthropic- header. |
safeguards | Undocumented | A list of safety checks, such as dangerous_, with the context that each check needs. |
system | Documented | An array of text blocks with cache_. |
tools | Documented | An array of tool definitions. |
messages | Documented | The conversation. An entry with role: can join in the middle. |
CLAUDE_ | Documented | An env var that adds fields to the body. |
The transcript line api-request records the request.
The lines api-request-shape and api-request-blob store parts of it once, by hash.
All three are Undocumented. See Transcript Format.
System Blocks and Cache Markers
A cache marker (cache_control) tells the API: "everything up to here can be reused."
An observed request had three system blocks and three markers.
| Position | Status | Marker |
|---|---|---|
system[0] (attribution line) | Undocumented | No marker. |
system[1] (identity line) | Undocumented | ephemeral, ttl:, scope:. |
system[2] (system prompt) | Undocumented | ephemeral, ttl:. |
| Last block of the last message | Undocumented | ephemeral, ttl:. |
Claude Code also marks the block of system context in the middle of a conversation, such as file-change notices, on every provider.
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS turns this off.
If a gateway rejects the marker with a 400 error, Claude Code moves it to the last message and keeps it there.
Cache Lifetime
Sources: How Claude Code Uses Prompt Caching: Cache Lifetime and Environment Variables.
| Item | Status | Effect |
|---|---|---|
| Main conversation | Documented | The cache lasts one hour on a Claude subscription within plan usage, and five minutes otherwise. |
| Subagents, workflows, forks, compaction, and titles | Documented | The cache lasts five minutes, except for some helper requests that the server sets. |
prompt, CLAUDE_ | Documented | Sets 5m or 1h for the main conversation. |
subagent, CLAUDE_ | Documented | Sets 5m or 1h for everything else. |
ENABLE_ | Documented | Asks for one hour in both groups. |
FORCE_ | Documented | Forces five minutes. It wins over the other items. |
DISABLE_ | Documented | Turns caching off. The suffixes _, _, _, and _ turn it off for one model family. |
DISABLE_ | Undocumented | Turns caching off for the Mythos models. |
CLAUDE_ | Undocumented | Appears in the env schema. No source states what it does. |
The cache is per machine and per folder, because the prompt holds memory paths and the working directory.
What Breaks the Cache
Source: How Claude Code Uses Prompt Caching.
| Action | Status | Effect |
|---|---|---|
| Switch model | Documented | Full miss. / asks first while the cache is warm. |
| Change effort | Documented | Full miss on most models. Opus 5.5, Sonnet 5.5, Haiku 5.5, and Fable 5.1 keep the cache. |
| Turn on fast mode | Documented | One miss, because a header joins the cache key. |
| Add or remove MCP tools that are not deferred | Documented | A miss. Deferred tools keep the first tool list for the conversation. |
| Deny a whole tool | Documented | A miss, because its definition leaves the list. |
Run / | Documented | A new prefix starts. |
| Upgrade Claude Code | Documented | A miss. |
| Enable a plugin with skills, agents, or hooks | Documented | No miss, because the content is appended. |
Per-Turn Values
Some models can take their effort level and the current time with each message.
Claude Code then sends them in a system entry of the message, with the betas per-turn-control-2026-07-01 and timing-2026-09-09.
These values are Undocumented. The capability flags per_turn_effort and per_turn_timing mark the models that accept them. See Models.
Facts From Probes
A local stub of the Messages API showed these facts. No model call left the machine.
- A model name with the
[1m]suffix adds thecontext-1m-2025-08-07beta. Without the suffix it is never sent. - The call to
/v1/messages/cache_touchneeds a subscriber login and thecache-keepalive-2026-09-03beta. It repeats every 30 seconds (10 to 120), with the body{"request_id": ...}.
What You Can Change
| Goal | How |
|---|---|
| Keep the cache alive longer | Set CLAUDE_ or ENABLE_. |
| Make a gateway happy | Set CLAUDE_. |
| Add a field to every request | Set CLAUDE_ to JSON. |
| Turn caching off | Set DISABLE_, or one family variant. |
| Avoid a miss | Pick the model and effort at the start of a session. |
| Keep machine facts out of the system prompt | Use --. It moves the working folder, environment, memory paths, and git status into the first user message. See The System Prompt. |
Example
You switch models in the middle of a task with /model.
The next request has no cache hits, because each model has its own cache.
Pick the model at the start of a session to avoid this.
ENABLE_PROMPT_CACHING_1H=1 claude --model sonnet
Related Pages
- The System Prompt
- Context and Compaction
- The Agent Loop
- Models
- API Endpoints and API Betas pages in Reference.