Prompt cache breakpoint on text that changes every call
Prompt caching on text that changes every call, so you pay to write and never read.
Why it costs money
With Anthropic prompt caching, writing a prefix to the cache costs more than normal input (1.25x for the 5-minute cache, 2x for the 1-hour cache), and reading it back costs 0.1x. The saving comes entirely from reads.
A cache hit requires the prefix to be identical. If the cached block includes a timestamp, a request id, retrieved documents or the user's message, the prefix is different every time. Every request pays the write premium and none of them get a read, so caching costs more than not caching at all. You can see it in usage: cache_creation_input_tokens on every call and cache_read_input_tokens always zero.
Example
Flagged
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
export async function answer(question: string) {
return anthropic.messages.create({
model: "claude-sonnet-4-5",
max_tokens: 1024,
system: [
{
type: "text",
text: STYLE_GUIDE + "Current time: " + new Date().toISOString(),
cache_control: { type: "ephemeral" },
},
],
messages: [{ role: "user", content: question }],
});
}Fixed
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
export async function answer(question: string) {
return anthropic.messages.create({
model: "claude-sonnet-4-5",
max_tokens: 1024,
system: [
{ type: "text", text: STYLE_GUIDE, cache_control: { type: "ephemeral" } },
{ type: "text", text: "Current time: " + new Date().toISOString() },
],
messages: [{ role: "user", content: question }],
});
}How to fix it
Put the cache breakpoint at the end of the part of the prompt that is identical across requests, such as instructions, a style guide or tool definitions. Move anything that varies (the time, retrieved documents, the user's input) after the breakpoint, where it is billed as normal input.
Then check a few responses: cache_read_input_tokens should be non-zero from the second request on. If it stays at zero, something inside the cached prefix is still changing.
What the audit detects
- Lines that set cache_control, excluding log statements and comments.
- The few lines just above the breakpoint are checked for per-request content: template interpolation, f-strings, Date.now(), new Date(), datetime, timestamps, uuid, random values or a user-role message. It also follows the cached variable within the same file to see whether it is built from retrieved context, chunks, documents or conversation messages.
- Breakpoints on tool definitions or schemas are skipped, and the breakpoint must sit on a message or text block.
Research
Anthropic docs: Prompt caching. Cache writes cost 1.25x to 2x the base input price and reads cost 0.1x. The breakpoint belongs on the last block whose prefix is identical across requests.