An agent can send the same instructions on every request and still miss its prompt cache. The instructions may be stable while the tool definitions ahead of them keep changing.
Before paying for longer retention or blaming the model, compare the requests your application actually builds. With Claude's prefix cache, an edited tool description can matter more than a paragraph of unchanged system instructions.
My recommendation is to treat the reusable prefix as a versioned interface: make accidental changes visible, put the cache boundary before volatile request data, and check the usage fields before choosing a repair.
This is a debugging procedure based on Anthropic's prompt-caching documentation, not a benchmark. I haven't measured a savings figure for it. The ordering and field names below are specific to Claude; another provider needs its own checks.
The tool list comes before the instructions
Anthropic documents the cache hierarchy as tools, then system, then messages. A change at one level invalidates that level and the levels after it. Editing a tool's name, description, or parameters in the original tools array can therefore invalidate reuse of the following system and message content.
Consider a hypothetical agent that rebuilds its registry for each request. The system instructions stay untouched, but a tool description includes a fresh timestamp or a changing list of available resources. Comparing only the system prompt would miss the difference that matters.
The same problem can arise without a deliberate content edit. Anthropic's troubleshooting guidance warns that unstable key ordering in tool_use content blocks can break cache matching. The serialized request deserves attention, not just the source template that produced it.
There is an important exception to the tool-change rule. On supported models, Anthropic documents a beta path for adding or changing tools through a tool_addition block in a mid-conversation system message while leaving the original tools array unchanged. That preserves the cached prefix. The documentation also notes a first-tool cache-miss exception when the original array has no non-deferred tool.
That is a separate implementation choice, not evidence that rewriting the original tool list is harmless. Check the supported-model tool-change mechanism before designing around it. An ordinary registry rebuild and an appended tool addition should not share the same label in your logs.
A breakpoint after a timestamp can cache the wrong boundary
Suppose independent requests contain stable instructions, then a current timestamp, then the question. If the only explicit cache breakpoint sits after the changing timestamp, each request writes a different prefix.
A longer lifetime keeps those entries around longer. It does not make their prefixes identical.
The fix for that request shape is to put an explicit breakpoint at the end of the stable prefix and keep the timestamp and incoming question after it. Anthropic explains that automatic prefix checking looks for entries written at previous breakpoints; it does not discover arbitrary stable content that was never written at a reusable boundary.
This example is about separate requests with a varying suffix. An append-only conversation preserves earlier blocks and can reuse earlier writes as it grows. Anthropic recommends automatic caching for many multi-turn conversations. Don't apply the timestamp diagnosis to a growing conversation without inspecting its actual block history and caching mode.
Establish a control before changing the registry
Use non-sensitive representative context. First confirm that the intended prefix meets the minimum cacheable length for the exact model and platform, and that the follow-up starts within the applicable cache lifetime. Keep the model, route, workspace, caching settings, and other request options constant.
Then run a few comparisons, changing one thing at a time:
- Write the static prefix, then send a matching follow-up with only the question changed after an explicit stable breakpoint. Check whether the response reports cache reads.
- Return to that control and change only one description in the original tool list. Compare the usage fields with the stable case.
- Test the independent-request timestamp placement: first before the only breakpoint, then after a breakpoint at the end of static context. Avoid changing the registry during this comparison.
These are proposed tests, not reported results. A missing cache read in the control is a reason to investigate the setup before attributing anything to the changed description.
The response's usage object provides the useful separation:
| Field | What Anthropic says it counts |
|---|---|
cache_creation_input_tokens |
Tokens written to a new cache entry |
cache_read_input_tokens |
Tokens retrieved from cache for this request |
input_tokens |
Input tokens neither read from nor used to create a cache entry |
A cache write proves that an entry was created. It doesn't prove that a later request reused it. Keep creation and read counts separate when comparing cases.
For the experiment record, retain the request-builder and tool-set version labels, model and route, prefix token length, elapsed interval, and these usage counters. You don't need a new store full of raw prompts, sensitive tool descriptions, or tool arguments to diagnose the boundary. Use deliberately non-sensitive fixtures and opaque version labels for the comparison.
Choose the repair that matches the evidence
If the stable control reads cache and the edited original tool list does not, investigate accidental registry churn. Give that workload a deliberate, reproducible tool set instead of generating a slightly different one on every call.
If moving the timestamp after a stable breakpoint restores reuse, fix the request builder's boundary. Buying longer retention would address a different problem.
If an unchanged request shape stops reusing the cache only after its lifetime elapses, retention becomes a reasonable candidate. Keep response duration in the timing record: Anthropic measures the lifetime from the start of the request that writes or reads the entry, not the end of its response.
If the control never reads cache, check the documented minimum length, matching content, isolation scope, request settings, and breakpoint lookback rules. The current documentation also links a cache-diagnostics feature that can compare consecutive requests. Follow the provider's troubleshooting guidance rather than assuming every miss has the same cause.
There may be little to optimize. If the workload has barely enough reusable context, or almost every request legitimately changes it, elaborate cache engineering may cost more than it saves. Measure repeated work in your own workload before committing to the maintenance.
Don't preserve the wrong tools to protect a cache hit
A stable prefix is useful only while its contents remain correct and authorized. Remove revoked tools. Refresh stale policy and source material. Accept the miss when the task requires a different tool set, or evaluate a supported tool-addition mechanism when that is appropriate.
The broader context-policy problem still governs what belongs in the request. Cache reuse is one resource decision inside that policy, alongside constraints such as the budget for parallel tool calls.
Before changing model tiers or extending retention, capture a stable control and one changed request. If the reusable prefix differs, repair accidental differences first. If it doesn't, let the usage fields point you toward the next check.