Why “Prompt Caching” Became 10× Charges on AWS Bedrock (and How to Fix It)
Picture this: you spin up Codex on AWS Bedrock to let an agentic coding workflow chew through a repo. Early runs look fine… until Cost Explorer starts lighting up like a warning dashboard. The scary part isn’t just that spend is higher. It’s directionally wrong—you expected caching to help, but costs behave as if the cache is never truly being used.
That’s the heart of a recent production report: native Codex requests to Amazon Bedrock for the GPT-5.6 Sol model were producing a very large volume of cache-write tokens, leading to materially higher cost. (docs.aws.amazon.com)
This post walks through what’s happening, why it’s specific to GPT‑5.6 explicit caching on Bedrock, and what a “correct” explicit-cache integration looks like.
The first mystery: what are cache-write tokens?
Start with the simplest mental model:
- Tokens are the chunks of text (or text derived from files/tools) that models process.
- Prompt caching means the service can reuse computations for repeated prompt prefixes instead of reprocessing them every time.
- Within cached prompting, two counters matter:
- cache_write_input_tokens: how many input tokens were written into the cache.
- cached_input_tokens (or cache read tokens): how many tokens were served from the cache.
On GPT‑5.6 models in Amazon Bedrock, caching isn’t symmetric. A cache read is heavily discounted, but a cache write is more expensive than an uncached read.
AWS describes this tradeoff clearly: cache reads are billed at a 90% discount, while cache writes cost 1.25× the uncached input rate. (aws.amazon.com)
So if your workload keeps forcing new cache writes instead of reusing existing cache entries, “prompt caching” can accidentally become “prompt reprocessing with extra charges.”
Why GPT‑5.6 on Bedrock needs explicit cache boundaries
Many people first meet prompt caching as something automatic: you send a long prompt, and the service figures out which parts to cache.
But GPT‑5.6 on Amazon Bedrock introduces a more controllable system: explicit cache breakpoints. Bedrock’s prompt caching documentation explains that GPT‑5.6 supports explicit breakpoints via the Responses API. ()
Two ideas are key:
1) prompt_cache_key = “which cache entry are we talking about?”
A cache key scopes cache reuse. If your stable prefix changes “identity,” the cache won’t match.
2) prompt_cache_breakpoint = “where does caching stop / start?”
A breakpoint marks the end of a reusable prefix. In other words: the service caches the earlier part, and the later part can change.
Bedrock also exposes cache modes under prompt_cache_options.mode:
implicit(default): Bedrock can place an automatic breakpoint on the latest message, while also honoring explicit ones.explicit: Bedrock disables the automatic breakpoint, and only explicit breakpoints are used. If you don’t provide explicit breakpoints, the request won’t use prompt caching and won’t incur cache-write charges. ()
This is the part that tends to surprise teams: in explicit mode, you’re taking responsibility for telling the system where “stable” ends and “variable” begins.
What goes wrong in agentic coding workloads
Agentic coding systems usually have this rhythm:
- Send a big chunk of stable context: system instructions, tool definitions, repository or reference files.
- Add the changing part: the current user request, the latest diff, the latest tool results, the next plan.
- Repeat many times while the agent refines its approach.
That pattern is exactly where prompt caching should shine—if the stable part stays stable and the cache boundary is placed correctly.
The production report described a workload where Codex emitted a session-scoped prompt_cache_key, but the requests did not include structured request-body fields for GPT‑5.6 explicit caching (namely prompt_cache_options and typed cache breakpoints). The net result: Bedrock kept treating large, repeated prefixes as something to re-write into cache, producing a high cache_write_input_tokens volume.
It’s also why the symptoms are so consistent with the economics of caching:
- Many requests → many cache writes.
- Cache writes cost more than the “ideal world” would suggest.
- Cached reads don’t grow fast enough to offset those writes.
In that report, estimated cache-aware spend for 2026‑08‑05 through 2026‑08‑08 showed cache writes dominating the total—cache writes were about 85% of the estimated Sol spend for that period.
A concrete “correct” Responses API shape (what you wanted to send)
Here’s the structure Bedrock documents for GPT‑5.6 explicit cache breakpoints. It’s shown as a Responses API request where the stable instruction block is cached and reused.
{
"model": "openai.gpt-5.6-sol",
"prompt_cache_key": "my-app:system-prompt-v1",
"prompt_cache_options": {
"mode": "explicit"
},
"input": [
{
"type": "message",
"role": "developer",
"content": [
{
"type": "input_text",
"text": "You are a technical support agent... (stable instructions)...",
"prompt_cache_breakpoint": {
"mode": "explicit"
}
}
]
},
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "How do I configure SSO for my organization? (variable)"
}
]
}
]
}
In the response, Bedrock returns usage fields that include cached-token accounting, such as cached tokens and cache write tokens.
Bedrock’s docs also call out the expected behavior: if the request fully hits the cache, you should see a large cached_tokens value and zero cache writes for those tokens. (docs.aws.amazon.com)
The “stable prefix” strategy: tools and system first, breakpoints after
Agentic prompts are rarely one blob. They’re a chain of content blocks: system instructions, tool definitions, reference documents, the latest user query, and then new tool outputs.
Bedrock’s caching guidance emphasizes a crucial ordering property:
- Cache hit rates improve when stable content comes before variable content.
- Cache checkpoints should be placed after the stable parts.
- The service evaluates the minimum cache size cumulatively across chained sections, and changing earlier sections invalidates later cached segments. ()
So the “fix” is less about sprinkling a single breakpoint everywhere, and more about treating prompt construction like an engineering artifact.
A practical rule of thumb for GPT‑5.6 explicit caching:
- Keep tool definitions and system/developer instructions stable across turns.
- Put the
prompt_cache_breakpointat the end of that stable region. - Ensure later blocks (the changing repo state, the newest tool outputs, the newest user directive) happen after the breakpoint.
Observability: how to confirm you’re getting cache reads, not cache writes
Even when caching is configured correctly, you need feedback loops.
Bedrock’s prompt caching docs show usage output that includes cache metrics (cached vs written tokens) inside the response usage object. ()
For a debugging mindset, treat these as separate “diagnostic buckets” rather than one blended “input tokens” number:
- If cache_write_input_tokens is large repeatedly, caching isn’t functioning as intended.
- If cached_input_tokens grows while cache writes stay low, your stable prefix is truly reusable.
In the reported case, local telemetry showed many Sol requests with millions of cache-write tokens and zero cached tokens—exactly the pattern that leads to surprise bills.
The engineering lesson: capability-gate caching fields by model
A subtle but important systems point: prompt caching isn’t one-size-fits-all.
For earlier GPT‑5.5 and earlier models, caching can be automatic and may not require explicit breakpoints. For GPT‑5.6, explicit breakpoints are the mechanism for precise cost control. ()
That makes model capability gating more than a nicety. It prevents “nearly right” request shapes that accidentally trigger expensive cache-write behavior without getting cache-read reuse.
In other words, the integration should follow this discipline:
- Detect the model generation (e.g., GPT‑5.6 Sol).
- Only serialize
prompt_cache_optionsandprompt_cache_breakpointwhen the model supports the explicit protocol. - Place breakpoints using a stable-prefix placement strategy.
- Emit cache read/write telemetry so failures are visible, not guessed at.
A quick closing reality check
Prompt caching is supposed to be a cost reducer, but the economics are unforgiving: on GPT‑5.6 in Amazon Bedrock, writing to cache is more expensive than uncached input, while reading from cache is heavily discounted. (aws.amazon.com)
So why did “prompt caching” lead to ~10× charges in that report? Because the workflow was effectively paying cache-write costs repeatedly without getting the corresponding cache-read reuse.
Once the explicit cache boundary is placed correctly—stable instructions/tools first, breakpoint after the stable prefix—the numbers move from “write-heavy churn” to “read-heavy reuse,” and the feature does what it’s meant to do.
Comments (0)
No comments yet. Be the first to respond!
Leave a Comment
Your comment will be visible after review.