Elevata

Article

A Codex Bug Can Make GPT-5.6 on Bedrock Cost 2.5x What It Should

Bruno Machado Valerio
View profilePublished July 27, 2026Updated July 29, 20267 min read

On 23 July, the Governance Gateway we run between Codex and Bedrock blocked an engineer after they hit their spending limit. The block was expected; reaching it that quickly was not. Confusingly, we saw that for this particular user the cost was related to Prompt-cache writes, we hadn’t seen this be a problem before, and the fact that it accounted for 90% of their costs was even more perplexing.

The billing data left us with two possibilities: either GPT-5.6’s cache-write price had made normal Codex traffic unexpectedly expensive, or Codex was sending requests in a way that prevented reuse. We traced the affected traffic from the Governance Gateway ledger to the exact JSON sent to Bedrock, then replayed those requests under controlled conditions.

The short version

  • For this user, cache writes accounted for 90% of GPT-5.6 costs. A write costs 1.25× ordinary input; a cache read costs 0.10×.
  • Codex could not mark the end of its stable startup content and changed the cache key for every session. The replay showed that both had to change.
  • With a breakpoint and a stable key, warm-request hit rates reached 96–97%, cache-write tokens fell 65% and total replay cost fell 59%.
  • The Governance Gateway can insert those fields before signing the request for Bedrock while preserving caching within each conversation. Direct traffic still needs the Codex change tracked in #35300.
Codex sends a JSON request through the Governance Gateway, the HTTP proxy between Codex and Amazon Bedrock. The model response returns through the gateway, which reads policies and limits from governance data and writes usage records back to it.
The Governance Gateway is the HTTP proxy between Codex and Bedrock. It reads policies and limits, rewrites cache fields, signs requests, records response usage and returns model responses to Codex. Direct requests are unchanged.

Cache writes made up 90% of one user’s GPT-5.6 costs

Because the Governance Gateway records token usage per request, we could isolate this engineer’s traffic. We reconciled that ledger against AWS Cost Explorer for OpenAI GPT-5.6 Sol (Amazon Bedrock Edition). Across complete days from 1 to 23 July 2026, filtered to RECORD_TYPE = Usage, their costs broke down as follows:

usage typetokenscostshare
cache write258.8M$1,780.3390.0%
output3.9M$127.566.5%
input9.8M$53.982.7%
cache read28.6M$15.710.8%
total$1,977.58

Write tokens outnumbered reads 9.1 to 1. Including uncached input, only 9.6% of input tokens came from cache. Over the same period, the same Codex path recorded 9.17M GPT-5.5 input tokens without a separate cache-write charge.

Under the Bedrock rates applicable to GPT-5.5, cache writes had no separate charge. GPT-5.6 prices a write at 1.25× ordinary input and a read at 0.10×. Rewriting a reusable prefix therefore costs 12.5 times as much as reading it. Those prices explain why the misses became expensive, but not why Codex kept missing.

Codex omits the breakpoint and changes the cache key

A prompt cache reuses an exact prefix, so it needs to know where stable content ends. Each codex exec request starts with instructions, tools and environment context; the task-specific input comes afterward. GPT-5.6 accepts this marker on the last stable content block:

"prompt_cache_breakpoint": {"mode": "explicit"}

Codex cannot construct that content-block field. Its relevant wire type has only:

pub enum ContentItem {
    InputText { text: String },
    ...
}

There is no map for additional fields, and the Responses request structs expose prompt_cache_key but not prompt_cache_options. Provider configuration changes connection behavior, not content nested inside input. Codex also generates the cache key from a fresh session UUID, so independent runs present the same prefix under different identities.

OpenAI’s GPT-5.6 migration guide is included in Codex. It describes the same pattern: a large stable prefix followed by a changing suffix can miss when the only managed breakpoint sits near the latest message. The guide recommends adding the marker above.

The breakpoint and stable key were both required

Because the Governance Gateway parses each request body before signing it for Bedrock, we could replay the bodies Codex had actually sent. An initial six-request test applied both changes together. The hit rate rose from 0% to 98.6%, and warm-request writes fell from about 9,060 tokens to 123–128. That told us the combined fix worked; the next question was whether both changes were necessary.

To find out, we varied the breakpoint and cache key independently across three captured requests:

configurationper-request hit ratecache-write tokens
Unmodified Codex0%, 0%, 0%16,873
Explicit breakpoint only0%, 0%, 0%16,873
Stable cache key only0%, 0%, 0%16,873
Breakpoint and stable key0%, 96%, 97%5,973 (-65%)

Only the final combination reused the prefix. Cache-write tokens fell by 65%, and the replay cost fell from $0.1161 to $0.0471 at the published Bedrock rates. The unmodified requests cost roughly 2.5 times as much.

That result is specific to what we observed on Bedrock Mantle. OpenAI describes prompt_cache_key as a routing hint used with the prefix hash, so other backends may behave differently.

Reading a cached prefix costs 0.10×; rewriting it costs 1.25×

For N requests sharing a prefix, writing it every time costs 1.25 × N. Writing once and reading afterward costs 1.25 + 0.10 × (N − 1).

requests sharing a prefixwrite every timewrite once, then readreduction
11.251.250%
22.501.3546.0%
33.751.4561.3%
56.251.6573.6%
1012.502.1582.8%

If a prefix will not be reused, a cache write costs 1.25 with no later saving. Explicit mode with no breakpoints leaves that request as ordinary input at 1.00.

Provider quotas differ. Bedrock excludes cache reads from applicable Mantle input-TPM quotas, while OpenAI’s API guide says cached prompts still count. GPT-5.6 has no published per-account Bedrock TPM quota, and we saw no throttling; in this incident, the measured effect was cost.

The Governance Gateway inserts the breakpoint and replaces the session key

For GPT-5.6 Responses requests from Codex, the Governance Gateway reads the JSON body, marks the last stable content block, replaces the session UUID with a scoped key, serializes the body again and signs the request for Bedrock. It leaves client breakpoints intact and skips content blocks that cannot hold a marker.

We leave prompt_cache_options.mode at its default. GPT-5.6 can then use our startup marker and still manage another breakpoint near the latest message. The startup marker supports reuse across sessions; the managed breakpoint supports later turns within one conversation. Forcing explicit-only mode with just the startup marker would remove that second benefit.

To prevent unrelated users or prompts from sharing a cache identity, the key is derived from the authenticated principal, model, prompt-and-tool version, tool schema and prefix fingerprint. The result is opaque and contains no PII or prompt text. OpenAI recommends keeping traffic near 15 requests per minute per key; deterministic shards can spread higher-volume traffic, at the cost of one cold write per shard.

Daily spend and token mix from 2026-07-21 to 2026-07-27 across all models. Spend peaks at 2,000.98 US dollars on 07-23 for 368.2m tokens, where cache writes are largest. By 07-25 spend is 625.64 dollars for 599.3m tokens and cache reads dominate.
All-model account totals. Breakpoint injection began on 24 July; cache reads then replaced much of the write volume while cost per million tokens fell. The controlled replay above was measured separately.

Codex 0.146.0 still cannot send the breakpoint

The stable Codex 0.146.0 release still cannot emit the breakpoint. Both that tag and the checked main snapshot retain an InputText variant containing only text. The request-construction issue remains open as #35300.

Merged PR #33454 reports cache_write_tokens in usage events and telemetry, but it does not change the request.

A native fix needs an optional breakpoint on supported content types, sent only to backends that accept it. Until then, our Governance Gateway has to add the field before Bedrock. Direct Codex-to-Bedrock traffic still misses it.

Cache reads and writes are part of input_tokens

In Bedrock Mantle responses, cache reads and writes are included within input_tokens; they are not additional tokens. Our cold and warm calls showed:

requestinput_tokenscache_write_tokenscached_tokens
cold5,3335,3310
warm5,33305,331
uncached_input = input_tokens - cached_tokens - cache_write_tokens

At the current US East GPT-5.6 Sol rates:

cost = uncached_input × $5.50/M
     + cache_write_tokens × $6.88/M
     + cached_tokens × $0.55/M
     + output_tokens × $33.00/M

Use the subtraction above for response data. In Cost Explorer and CUR, ordinary input, writes and reads already appear as separate rows, so sum those rows instead.

  • Use RECORD_TYPE = Usage and closed days in Cost Explorer; current periods are estimated.
  • Treat 30m in a usage type as the documented 30-minute minimum lifetime, not an exact expiry. A cold test needs a unique prefix or key.
  • The published AWS/BedrockMantle metrics expose no cache-specific field. Persist read and write details per response.

Repeated cache writes made the same requests cost 2.5x more

Once we could see the request bodies, the cause was straightforward: Codex repeated the same startup content but gave Bedrock neither a stable boundary nor a stable cache identity. Bedrock kept writing a prefix it could have read.

The Governance Gateway now supplies both for routed traffic, cutting replay cost by 59% without sacrificing the cache for later conversation turns. Direct Codex-to-Bedrock requests do not pass through that fix, so Codex still needs native breakpoint support.

Related reading: Codex and OpenAI Agents on Amazon Bedrock, governing Claude Code, Claude Desktop and Codex behind one Governance Gateway, and Claude Code on AWS.

Related

Continue reading

Related reading on this topic.