Invalidation hierarchy and silent invalidators
Not every change invalidates everything — and the ones that do are predictable.
5 min read · Lesson 3 of 9 in this domain
Not every change is equally destructive, and the hierarchy is worth knowing because it tells you what you can safely vary per request. Changes invalidate their own tier and everything below it. Tool definitions and the model sit at the top: change either and the whole cache is gone. The system prompt sits below them, and message content below that. The useful consequence is that tool_choice and toggling thinking are below the tools-and-system tier, so you can vary them freely per request while keeping that expensive prefix intact.
- Changes only invalidate their own tier and below. So
tool_choicecan vary per request while the tools-and-system cache survives. - Tool definition changes and model switches invalidate everything. Caches are model-scoped.
- Consequence for "modes": do not swap the tool set mid-conversation. Signal the mode through message content, or use tool search, which appends rather than swaps.
- Consequence for cheaper sub-tasks: keep the main loop on one model and delegate to a subagent rather than switching models mid-conversation.
- Silent invalidators to grep for in prompt-building code:
datetime.now()or a UUID in the system prompt,json.dumps()withoutsort_keys, iterating a set, a per-user id interpolated into the system prompt, and conditional system sections. - The fix is always the same shape: keep the system prompt frozen, move volatile content after the last breakpoint.
| What changed | Tools cache | System cache | Messages cache |
|---|---|---|---|
| Tool definitions | Invalid | Invalid | Invalid |
| Model switch | Invalid | Invalid | Invalid |
| System prompt text | OK | Invalid | Invalid |
| tool_choice / thinking toggle | OK | OK | Invalid |
| Message content | OK | OK | Invalid |
Assuming a per-user id is "too small to matter". A one-character difference at the front kills cross-user sharing entirely.
Which change can vary per request without losing the tools-and-system cache?
tool_choice sits below tools and system in the invalidation hierarchy.
A sub-task needs a cheaper model. Best approach?
Caches are model-scoped, so switching invalidates in both directions.
Practise this domain with 15%%-weighted questions in the study app.
Open in study appSource: Claude Docs — Prompt caching · Independent study aid, not affiliated with or endorsed by Anthropic.