Skip to content

    Token optimisation

    Prompt caching explained: how to stop paying twice for the same tokens

    Caching is prefix-based, which means one timestamp in the wrong place can cost you the entire discount. Here is how it actually works and how to structure prompts so it fires.

    10 min readUpdated

    Prompt caching is the highest-return, lowest-risk change available in most AI systems, and it is also the one most often left half-working. The discount on repeated input is steep across every major provider. The requirement for earning it is unforgiving in a way that catches nearly everybody the first time: the repeated content has to be a byte-identical prefix.

    This guide covers what that means mechanically, the four ordering mistakes that disable caching by accident, and how to tell whether yours is working.

    What providers are actually charging you for

    When a model processes your prompt, it computes an internal representation of every token — the attention key/value state. That computation is a large share of what input tokens cost. If two requests begin with exactly the same tokens, the state for that shared beginning is identical, so it can be computed once and reused.

    That is the whole trick, and it explains every rule that follows. Reuse is possible only from the start of the prompt and only up to the first token that differs, because everything after a change has different context and must be recomputed. This is why caching is described as prefix-based rather than as a lookup table: there is no partial credit for repeated content in the middle of a prompt.

    Commercial terms differ by provider and change over time: some apply caching automatically above a minimum prefix length, others require an explicit marker in the request; some charge a small premium to write a cache entry in exchange for a much larger discount on reads; retention windows range from minutes to considerably longer, usually extended by reuse. Check your provider's current documentation for the numbers — but the mechanism above is universal, and it is the mechanism that dictates how you write the prompt.

    The four ways teams disable caching by accident

    1. Volatile content near the top

    This is the big one, and it is almost always unintentional. A prompt assembled as “you are a helpful assistant… / today's date is 30 August 2026 / the user is Sarah Chen / here are the retrieved documents… / here is the question” looks perfectly sensible and caches nothing beyond the first line, because the date and the name change and everything after them is therefore new on every request.

    The fix costs nothing and changes nothing about the output. Order the prompt from most stable to least stable:

    1. 1System instructions, role, rules, output format — identical for every user, forever.
    2. 2Tool and function definitions — stable until you ship a change.
    3. 3Few-shot examples — stable, and worth keeping in a fixed order.
    4. 4Long shared reference material — a policy document, a schema, a codebase file.
    5. 5Per-user or per-session context — profile, permissions, conversation summary.
    6. 6Retrieved context for this request.
    7. 7The volatile scraps: current date, request ID, timestamps.
    8. 8The user's actual question, last.

    If the model genuinely needs today's date to answer well, it does not need it in line two. Putting it immediately before the question works just as well and preserves everything above it.

    2. Byte-identity broken by serialisation

    “Identical” means identical bytes, not identical meaning. Several common patterns break this without any visible change to the prompt:

    • JSON serialised with non-deterministic key ordering — the same object, a different byte string.
    • Trailing whitespace or line-ending differences introduced by templating.
    • Few-shot examples shuffled per request to “avoid position bias”, which also shuffles away the cache.
    • A framework that rebuilds the system message with a fresh UUID, trace ID or timestamp header.
    • Prompt fragments interpolated from a set with non-deterministic iteration order.

    The diagnostic is straightforward: log the exact serialised prefix for two consecutive requests and diff them. Teams are routinely surprised by what shows up.

    3. A prefix shorter than the provider's minimum

    Providers impose a minimum cacheable prefix length. Below it, nothing is cached however stable the content is. Systems with very short system prompts and long user inputs sometimes sit just under the threshold and see no benefit at all — occasionally worth restructuring toward, if there is genuinely stable material that could be promoted into the prefix.

    4. Traffic too sparse to keep the cache warm

    Cache entries expire. A workload with one request every twenty minutes may never hit a warm cache, while the same prompt structure under continuous traffic hits it almost always. This is why the same code can show excellent cache rates in production and none at all in a staging environment, and why batching related work together in time can be worth doing for cost reasons alone.

    Designing for cacheability from the start

    Once the prefix rule is internalised, some architectural choices become obvious.

    ChoiceEffect
    One large stable system prompt for a featureExcellent — the whole thing is cacheable across every user
    Per-user personalised opening paragraphPoor — splits the cache per user and blocks everything below
    Rolling conversation summary at a fixed positionGood — stable within a session, and far shorter than raw history
    Full raw transcript resent each turnPoor and worsening — the prefix grows and changes every turn
    Retrieved chunks sorted by relevance scoreFragile — reordering on near-ties changes the bytes
    Retrieved chunks in a stable canonical orderBetter — same content, deterministic serialisation
    Design choices and their effect on cacheability

    The conversation-history case is worth dwelling on because it compounds with the quadratic cost problem. Replacing a growing raw transcript with a summary plus the last few turns does two things at once: it stops the input growing without bound, and it makes the earlier part of the prompt stable enough to cache. The two effects multiply rather than add.

    How to tell whether it is working

    Providers report cached input tokens separately in the usage object on each response. That field is the ground truth, and it belongs on a dashboard.

    • Track cache hit rate as cached input tokens divided by total input tokens, per feature rather than estate-wide.
    • Alert on a drop. A prompt edit that reorders the template will show up here immediately and nowhere else.
    • Assert on it in tests where it matters: a test that fails when the stable prefix stops being stable is cheap to write and catches the regression at review time.
    • Compare cost per successful task before and after, not just the token counts — caching changes the bill without changing the answers, so the ratio should move cleanly.

    Restructuring prompts for caching is usually the first phase of our implementation work.

    Prompt, context and caching engineering

    FAQ

    Questions this guide gets asked

    How does prompt caching work?

    Providers cache the computed internal state for the beginning of your prompt and reuse it when a later request starts with exactly the same tokens. Reuse runs from the first token up to the first byte that differs, which is why the repeated content must sit at the front of the prompt and be byte-for-byte identical between calls.

    Why isn't my prompt caching working?

    In roughly that order of likelihood: something volatile sits near the top of the prompt, such as a timestamp, user name or request ID; serialisation is not deterministic, so the bytes differ even though the content does not; the stable prefix is shorter than the provider's minimum; or your traffic is too sparse to keep an entry warm between requests.

    Does prompt caching change the model's output?

    No. The model receives exactly the same tokens in exactly the same order — caching only changes how the provider computes and bills the prefix. That is what makes it safe to ship without an evaluation harness, unlike changing the model or trimming context.

    Should the conversation history go before or after the retrieved documents?

    Put whatever is more stable first. In most chat products a rolling summary is more stable than freshly retrieved documents, so summary before retrieval caches better. If your retrieval is dominated by one large fixed corpus and the conversation changes every turn, invert it. The rule is stability order, not category order.

    Find out what your AI actually costs per completed task.

    Two weeks, a fixed fee, and a ranked savings plan with the quality risk of every move stated up front. If the numbers say an audit is not worth it for you, we will say so on the first call.