Keep the prompt prefix byte-stable so cache hits survive
Prompt caches match on an exact prefix. A timestamp, a rotating session id, or dynamic tools at the top of the system prompt quietly forces a full-price rebuild on every call.
The problem
Providers bill a cached prompt read at a fraction of the normal input price (Anthropic’s 5-minute cache is about 0.1×). That only helps if the next request starts with the exact same bytes. Put a timestamp, a request id, or a freshly assembled tool list at the top of the system prompt and the cache misses from the first character. Every call then pays full input price for tools, rules and history that barely changed.
The tip
Treat the prompt like a content-addressed blob:
- Static first. Tools, system instructions, long reference docs — anything that stays the same across turns — go at the top.
- Dynamic last. Timestamps, user ids, retrieved docs, the latest message — append them after a cache breakpoint.
- Don’t poke the prefix mid-session. Switching models, connecting or disconnecting an MCP server, or rewriting the system prompt mid-flight invalidates everything after the change. Compaction does too; treat it as a deliberate cache reset.
@amitsinha__07’s one-liner: “a timestamp at the top of your system prompt quietly kills prompt caching.” Put static instructions and tools first, dynamic data last.
Example
# Bad: dynamic content at the top → cache miss every call
system = f"Session started at {now.isoformat()}\n" + RULES + TOOLS
# Good: stable prefix first, dynamic fields last
system = RULES + TOOLS # byte-stable across turns
user = f"User timezone: {tz}\nRequest id: {rid}\n\n{user_msg}"
# Mark a cache breakpoint at the end of the static block (SDK-specific).
(Exact cache_control shape depends on the SDK; the ordering rule does not.)
When NOT to use it
Don’t freeze a prefix that must change for safety — for example, when you intentionally rotate a system rule after a jailbreak attempt, or when you compact a 400K context down. Those are real invalidations. Also, very short prompts often sit under the provider’s minimum cacheable size, so the tip doesn’t buy you anything until the static block is large enough.