GPT-5.6 prompt caching: Codex cannot emit `prompt_cache_breakpoint`, preventing reuse of stable startup prefixes

Open 💬 6 comments Opened Jul 25, 2026 by davelindo

Summary

GPT-5.6 supports an explicit prompt_cache_breakpoint on the content block that ends a reusable prefix. Codex's own vendored migration guide (codex-rs/skills/src/assets/samples/openai-docs/references/upgrading-to-gpt-5p6-sol.md:210) describes this exact failure mode:

GPT-5.6 implicit caching places a managed breakpoint near the latest user or tool message and no longer relies on 128-token rounding. A prompt with a large stable prefix followed by a changing suffix can therefore lose cache hits even when the stable prefix itself has not changed.

Its remedy, at line 242: "Place explicit breakpoints at the actual stable rendered boundary using prompt_cache_breakpoint." And at line 244, why this now costs money: "Cache writes cost more than ordinary uncached input, so a lower hit rate can be both slower and more expensive."

Codex cannot emit the field. ContentItem::InputText and InputImage have no prompt_cache_breakpoint member or extension map, so the documented field is unrepresentable in both HTTP and WebSocket request construction.

In a controlled replay of real Codex request bodies with the same ~9k-token developer prefix, a fixed prompt_cache_key, and only the final user message changed, unmodified requests produced 0% cache hits and rewrote ~9,060 tokens each. Adding only prompt_cache_breakpoint: {"mode":"explicit"} to the final stable input_text block produced 98.6% hits and reduced warm-request writes to 123–128 tokens.

This does not affect every turn. Append-only continuation turns within a single session already reached ~98% hits. The demonstrated failure is reuse of a stable startup prefix when independent requests diverge at the first volatile user turn.

The source-level defect is the missing content-block field. Session-scoped cache keys are a separate compounding issue on the measured backend, automatic breakpoint placement is a policy decision, and prompt_cache_options is optional API completeness.

Environment

| | |
|---|---|
| Codex CLI | 0.145.0 and 0.146.0-alpha.10, tested as of 2026-07-24 |
| Source refs | rust-v0.145.0 (25af12f7e615), rust-v0.146.0-alpha.10 (ae83c6df6ffd), and main @ 4c43465133428898aa84f0bfc02c306ed65fb66a |
| Model measured | gpt-5.6-sol |
| Also affected by the wire-type gap | gpt-5.6-terra, gpt-5.6-luna |
| Backend measured | AWS Bedrock Mantle, OpenAI-compatible Responses API (/openai/v1/responses) |
| Wire API | responses, streaming |
| Platform | macOS 27.0 arm64 |

The measurements below are from Bedrock Mantle. The serialization defect is backend-independent and directly verifiable from the Codex source, but absolute cache behavior and billing should also be reproduced against api.openai.com before being treated as universal.

Expected behavior

OpenAI's prompt-caching guide documents that GPT-5.6 and later models can mark the exact end of a reusable prompt prefix by adding:

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

to a supported content block. Content after that block may then change without invalidating the earlier cached prefix.

Codex should at minimum be able to represent and serialize this field on supported content blocks. Whether Codex places breakpoints automatically, exposes them through configuration, or both is a separate default-policy decision. The vendored migration guide explicitly advises using explicit breakpoints only for measured stable boundaries and not converting every prompt globally.

Actual behavior

Codex always relies on the implicit managed breakpoint because it has no wire representation for an explicit one. When requests share a large startup prefix but differ at the first volatile user turn, Codex cannot mark the actual stable boundary.

On the measured workload, those requests missed and rewrote essentially the entire eligible prefix. In contrast, ordinary append-only turns within one session cached normally because each prior turn became stable prefix for the next.

Minimal source proof

The content-block field is unrepresentable

codex-rs/protocol/src/models.rs:702 in rust-v0.145.0 and :706 on the cited main revision:

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentItem {
    InputText {
        text: String,
    },
    InputImage {
        image_url: String,
        #[serde(default, skip_serializing_if = "Option::is_none")]
        #[ts(optional)]
        detail: Option<ImageDetail>,
    },
    InputAudio {
        audio_url: String,
    },
    OutputText {
        text: String,
    },
}

There is no prompt_cache_breakpoint field and no #[serde(flatten)] or extra-fields map. The API supports breakpoints on input_text, input_image, and input_file, but Codex cannot serialize one on any of those blocks.

The top-level cache options are also absent

ResponsesApiRequest and ResponseCreateWsRequest both contain prompt_cache_key, but neither contains prompt_cache_options or an arbitrary request-body extension map:

pub struct ResponsesApiRequest {
    // ...
    pub prompt_cache_key: Option<String>,
    pub text: Option<TextControls>,
    pub client_metadata: Option<HashMap<String, String>>,
}

This is not required for the measured hit-rate recovery: the A/B below used a content-block breakpoint without sending prompt_cache_options. It is listed separately because the same GPT-5.6 API surface is incomplete in both the HTTP and WebSocket request structs.

Configuration cannot work around the missing nested field

ModelProviderInfo accepts connection-level customization such as base_url, wire_api, headers, query parameters, and retry controls, but no request-body transformation. The schema uses additionalProperties: false, so a user cannot add a nested prompt_cache_breakpoint through config.toml.

A top-level request-body passthrough such as #34569 could expose prompt_cache_options, but it would not solve the core bug unless it also supported structured transformation inside input.

Controlled reproduction

Procedure

  1. Configure Codex with a recording custom model_provider using wire_api = "responses".
  2. Capture a real codex exec request body.
  3. Replay the body several times with:
  • one fixed prompt_cache_key;
  • an identical developer prefix;
  • only the final user message changed between requests.
  1. Record usage.input_tokens_details.cached_tokens and cache_write_tokens.
  2. Repeat with the same bodies, adding only the following field to the last input_text block in the stable developer prefix:
"prompt_cache_breakpoint": {"mode": "explicit"}

The measured bodies used the non-lite request shape because the production gateway rejects the proprietary additional_tools item. The serialization gap is the same in the Responses Lite path; only the correct placement differs.

Result

The first request in each arm was a cold write. The table below compares the three subsequent requests.

| request form | input tokens | cached tokens | cache-write tokens | hit rate |
|---|---:|---:|---:|---:|
| Unmodified Codex #1 | 9,067 | 0 | 9,065 | 0% |
| Unmodified Codex #2 | 9,062 | 0 | 9,060 | 0% |
| Unmodified Codex #3 | 9,065 | 0 | 9,063 | 0% |
| Breakpoint #1 | 9,067 | 8,937 | 128 | 98.6% |
| Breakpoint #2 | 9,062 | 8,937 | 123 | 98.6% |
| Breakpoint #3 | 9,065 | 8,937 | 126 | 98.6% |

No prompt_cache_options were sent. The only request-body change was the content-block breakpoint.

Scope and non-claims

  • This report does not claim every Codex request misses cache. Five sequential turns in one unmodified session reached approximately 98% hits after the cold turn.
  • The controlled A/B establishes causality for a stable prefix followed by a changing tail. It does not establish that every cache write on the provider invoice was caused by this defect.
  • The source-level bug is inability to represent the field. Automatic insertion, stable-key policy, and top-level cache options may be fixed together or handled separately.
  • The measured requirement for a stable cross-session key is specific evidence from Bedrock Mantle. OpenAI documents prompt_cache_key as a routing and matching hint, not a guaranteed hard cache partition.

Suggested minimum fix

  1. Add an optional breakpoint field to supported content variants, at least ContentItem::InputText and InputImage, with skip_serializing_if = "Option::is_none". Add InputFile support when that content variant exists.
  2. Add serialization tests proving that the field is emitted only on supported content blocks and omitted by default.
  3. Gate use through an explicit model/provider capability such as supports_prompt_cache_breakpoints. Do not infer support solely from a model-name string, because custom providers may expose different request capabilities.
  4. Provide a code path that can mark the end of a measured stable rendered prefix. Automatic placement can remain conservative or opt-in; the minimum requirement is that the documented field be representable.

Follow-up improvements that are useful but not required to establish or fix the core serialization defect:

  • derive or expose a cache key that can remain stable across independent requests with the same startup context, while respecting the documented request-rate guidance per key;
  • add prompt_cache_options: Option<PromptCacheOptions> to both HTTP and WebSocket request structs;
  • audit CompactionInput, which also carries prompt_cache_key without prompt_cache_options, after confirming whether the specialized compact endpoint accepts the field.

<details>
<summary><strong>Additional measurements</strong></summary>

Intra-session continuation already caches correctly

Five sequential turns from one unmodified Codex session:

| turn | input | cached | writes | hit rate |
|---|---:|---:|---:|---:|
| 1 | 9,093 | 0 | 9,091 | 0% |
| 2 | 9,244 | 9,091 | 151 | 98% |
| 3 | 9,385 | 9,242 | 141 | 98% |
| 4 | 9,559 | 9,383 | 174 | 98% |
| 5 | 9,771 | 9,557 | 212 | 98% |

This is why the issue is easy to miss when inspecting a long interactive session: the implicit tail breakpoint works for monotonically growing history.

Cross-session key interaction on Bedrock Mantle

Three captured codex exec bodies contained 5,621 / 5,641 / 5,617 input tokens and differed in their volatile tails. Each arm replayed those same fixed bodies.

| configuration | per-request hit rate | total cache-write tokens |
|---|---|---:|
| Unmodified Codex | 0%, 0%, 0% | 16,873 |
| Explicit breakpoint only | 0%, 0%, 0% | 16,873 |
| Stable prompt_cache_key only | 0%, 0%, 0% | 16,873 |
| Breakpoint and stable key | 0%, 96%, 97% | 5,973 (−65%) |

The inputs total 16,879 while the full-miss writes total 16,873 because the provider reported two fewer write tokens than total input on each request.

This establishes that, on the measured backend, a stable key was also needed for independent sessions to realize reuse. It is a compounding key-policy issue, not evidence that the missing breakpoint field itself is backend-specific.

Other causes tested

  • A 101,448-token prefix cached at 99% with a breakpoint, so this was not a prefix-size ceiling.
  • Six byte-identical concurrent requests on a warm key all hit 99%, distinguishing this test from #33821.
  • stream: true and stream: false behaved the same.
  • Reasoning efforts from low through xhigh showed the same baseline miss pattern.
  • Carrying reasoning items and requesting reasoning.encrypted_content had no measurable effect after the arms were pre-warmed identically.

</details>

<details>
<summary><strong>Request shapes and breakpoint placement</strong></summary>

All three shipped GPT-5.6 catalog entries have use_responses_lite: true, but custom providers may use the non-lite path.

Responses Lite

Codex prepends an additional_tools developer item and a developer message containing base instructions to input; top-level instructions and tools are omitted.

{
  "model": "gpt-5.6-sol",
  "prompt_cache_key": "<session UUID>",
  "input": [
    {"type": "additional_tools", "role": "developer", "tools": ["..."]},
    {"type": "message", "role": "developer", "content": [
      {"type": "input_text", "text": "..."}
    ]},
    {"type": "message", "role": "developer", "content": [
      {"type": "input_text", "text": "..."},
      {"type": "input_text", "text": "..."}
    ]},
    {"type": "message", "role": "user", "content": ["..."]}
  ]
}

additional_tools has no content block on which to place a breakpoint. A placement algorithm would need to mark the last supported content block in the measured stable developer portion, not the additional_tools item itself.

Non-lite Responses

instructions and tools remain top-level, while leading developer messages are in input:

{
  "model": "gpt-5.6-sol",
  "prompt_cache_key": "<session UUID>",
  "instructions": "...",
  "input": [
    {"type": "message", "role": "developer", "content": [
      {"type": "input_text", "text": "..."},
      {"type": "input_text", "text": "..."}
    ]},
    {"type": "message", "role": "user", "content": ["..."]}
  ],
  "tools": ["..."]
}

The controlled A/B marked the last input_text block in the stable developer item. An implementation must not assume every developer-role item is stable: current time, workspace data, permissions, tool availability, and project instructions can vary. The boundary should be based on the rendered stable portion, splitting content blocks where necessary.

</details>

<details>
<summary><strong>Cost impact and provider billing evidence</strong></summary>

GPT-5.6 cache writes are billed at 1.25× uncached input, while cache reads are billed at 0.10×. A write therefore costs 12.5× a read. Earlier model families did not expose the same cache-write line-item cost.

AWS Cost Explorer for OpenAI GPT-5.6 Sol (Amazon Bedrock Edition), 2026-07-01 through 2026-07-23 complete days, filtered to RECORD_TYPE = Usage:

| usage type | tokens | cost | share of model spend |
|---|---:|---:|---:|
| cache_write_tokens_30m_standard | 258.8M | $1,780.33 | 90.0% |
| output_tokens_standard | 3.9M | $127.56 | 6.5% |
| input_tokens_standard | 9.8M | $53.98 | 2.7% |
| cache_read_tokens_standard | 28.6M | $15.71 | 0.8% |
| Total | | $1,977.58 | |

Cache-write tokens were 9.1× cache-read tokens. Counting uncached input, cache writes, and cache reads together gives a 9.6% aggregate cached-token share.

For comparison, the same client and gateway against OpenAI GPT-5.5 (Amazon Bedrock Edition) billed 9.17M input tokens and zero cache-write tokens over the same period.

What this evidence establishes:

  • cache-write volume is a material real-world cost on this GPT-5.6 workload;
  • the provider's implied unit prices reproduce the documented write/read multipliers;
  • the controlled replay shows that a correctly placed breakpoint can eliminate most warm writes for the tested request pattern.

What it does not establish:

  • that this defect caused every one of the 258.8M cache-write tokens;
  • the share attributable to cold starts, genuinely distinct prefixes, compaction, or other prefix churn;
  • universal savings on other providers or workloads.

Applying the controlled reductions to all invoice writes would imply approximately $1,157 at the 65% cross-session reduction or $1,745 at the 98% same-prefix A/B reduction. Those are illustrative upper bounds, not attributable savings.

</details>

<details>
<summary><strong>Relationship to existing issues</strong></summary>

| issue | relationship |
|---|---|
| #34569 | Confirms that ModelProviderInfo has no generic top-level request-body extension. It could expose prompt_cache_options, but not a nested content-block breakpoint without structured input transformation. |
| #31882 | use_responses_lite changes the rendered prefix shape and therefore where an automatically inserted breakpoint would belong. |
| #32479 / PR #33454 | Cache-write usage is now carried through Codex for API-key/provider responses. The issue remains open because subscription-backed responses may still report zero. |
| #24704 | Closest prior art for preserving cache lineage in forked subagents; discussion mentions an inherited key and explicit inherited-prefix boundary, but not the missing serialization field. |
| #29377 / #21796 / #26283 | Overlap with the separate request for stable or configurable cache keys. |
| #20301 | Similar low-hit symptom on GPT-5.5, but this report does not establish its cause and the GPT-5.6 breakpoint API does not apply there. |
| #30425 | Reports intermittent misses on repeated bodies. A truly byte-identical body also has an identical implicit breakpoint, so the missing explicit field does not by itself explain that issue. |
| #33821 | Concurrent identical requests can split between hit and miss. Concurrency reproduced cleanly in this test, so it appears separate. |
| #32613 | Image-triggered invalidation may be adjacent because GPT-5.6 supports image-block breakpoints, but no causal link is established here. |

No issue found in the searched set reports that prompt_cache_breakpoint is structurally unserializable in Codex, and no open PR found in that search addresses it.

</details>

<details>
<summary><strong>Verification notes</strong></summary>

  • The cache-relevant source was checked at rust-v0.145.0, rust-v0.146.0-alpha.9, rust-v0.146.0-alpha.10, and the cited main revision. Relevant line numbers move, but the missing fields remain.
  • git grep -l -E 'prompt_cache_options|prompt_cache_breakpoint' <ref> returned only the vendored migration-guide markdown asset and no Rust implementation at the checked refs.
  • ResponsesApiRequest changed between stable and prerelease for unrelated tool serialization, confirming the request struct has been edited recently without adding these cache fields.
  • The replay fixtures, proxy transform, and raw provider responses are not embedded in this issue body. The source-level defect is independently verifiable without them; the controlled measurements should be treated as author-supplied evidence unless a sanitized bundle is attached.
  • The AWS figures can be reproduced with Cost Explorer by filtering the model service to RECORD_TYPE = Usage and grouping by USAGE_TYPE. UsageQuantity is reported in millions of tokens.

</details>

View original on GitHub ↗

6 Comments

RocStone · 22 days ago

I reproduced the cross-thread failure on the ChatGPT Codex subscription backend, using a custom Codex build based on rust-v0.146.0 and gpt-5.6-sol.

Controlled setup:

  • one root thread with a stable 41,452-token ancestor;
  • two persistent forks, each with its own thread ID, session ID, rollout JSONL, and WebSocket connection;
  • both forks explicitly used the same root prompt_cache_key;
  • A completed before B started, so this run had no concurrent-request race;
  • model, instructions, tools, request properties, and the complete ancestor item sequence were identical; only the final branch user item differed.

WebSocket result:

| branch | input | cached | ancestor coverage |
|---|---:|---:|---:|
| A | 41,488 | 5,888 | 14.2% |
| B | 41,488 | 5,888 | 14.2% |

I repeated the same experiment with WebSockets disabled, forcing full HTTP Responses requests. The stable ancestor was 42,387 tokens, both forks again used the same root cache key, and all cache-relevant request fingerprints plus the full ancestor item sequence matched:

| branch | input | cached |
|---|---:|---:|
| A | 42,423 | 0 |
| B | 42,423 | 0 |

The root's ordinary append-only turns did cache within the same run (18,176 cached on turn 2 and 31,488 on turn 3), so the account/backend was caching. The failure begins when the stable history is replayed into independent forked sessions.

This supports the issue's distinction between append-only intra-session caching and independent requests that diverge after a stable ancestor. A shared prompt_cache_key alone did not preserve the ancestor cache on the ChatGPT subscription backend.

I also manually probed explicit prompt_cache_breakpoint against the ChatGPT Codex backend with both Sol and Luna routes; the backend rejected the parameter as unsupported. That leaves a subscription client unable to apply the documented GPT-5.6 remedy even after adding the missing Codex wire representation.

Questions for maintainers:

  1. Is prompt_cache_breakpoint intended to be supported by chatgpt.com/backend-api/codex/responses for GPT-5.6?
  2. If it is intentionally unavailable there, what supported mechanism should Codex use to retain a stable ancestor cache across forked threads/sessions?
  3. Is cache matching on this backend scoped by thread/session state in addition to prompt_cache_key and the rendered prompt prefix?

These results were collected within one cache-TTL window. The fork requests contained no sibling content.

RocStone · 22 days ago

Follow-up with the missing orthogonal control: I reran the same 41,452-token ancestor on the same gpt-5.6-sol build, still dispatching A first and B only after A completed.

  • A and B kept in one Codex thread/session: both cached 40,704 tokens (98.20% ancestor coverage).
  • A and B forked into two Codex threads/sessions with the same root prompt_cache_key: both cached only 5,888 tokens (14.20% ancestor coverage).

The model, stable ancestor, cache key, order, and branch prompts were held constant. Splitting the execution into independent thread/session/connection state is the variable that caused the cache loss; concurrency is not required to reproduce it.

rebroad · 21 days ago

I hit this exact failure in session 019fd916-3d94-7b01-b3ff-cbf95071f34b on 2026-08-06 with gpt-5.6-luna.

The final five Responses API calls were:

| timestamp | uncached input | cached input | output | cost |
|---|---:|---:|---:|---:|
| 22:23:14.319Z | 206 | 135,936 | 31 | $0.002797 |
| 22:28:04.511Z | 143,985 | 0 | 67 | $0.028877 |
| 22:28:17.715Z | 976 | 143,104 | 31 | $0.003094 |
| 22:33:08.523Z | 144,134 | 0 | 70 | $0.028911 |
| 22:33:21.719Z | 1,128 | 143,104 | 31 | $0.003125 |

The two full misses occurred immediately after completed long-running tool calls (about 287 seconds each). In both cases, the next continuation roughly 13 seconds later reused 143K cached tokens. The request context was otherwise append-only and about 144K tokens, so this does not look like genuine context churn or cache expiry.

This is a concrete billing impact: the two misses cost about 9x more than their immediately-following cached continuations. It appears consistent with GPT-5.6's latest-tool implicit breakpoint invalidating the full prefix when the completed tool output changes, exactly as described in the issue.

StartupBros · 8 days ago

ChatGPT subscription backend reproduction: explicit GPT-5.6 cache controls are rejected, and same-key append-only turns still miss intermittently

We reproduced the subscription-backend half of this issue under sustained, naturally initiated Claude Code traffic routed to https://chatgpt.com/backend-api/codex/responses.

Capability result

We enabled a deterministic treatment that changed only one field: it added

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

to a historical stable input_text block while preserving the physical model, account, endpoint, request ordering, tools, instructions, and existing conversation-scoped prompt_cache_key.

Results:

| model | treatment requests | HTTP 400 | successful cache measurements |
|---|---:|---:|---:|
| gpt-5.6-sol | 18 | 18 | 0 |
| gpt-5.6-terra | 8 | 8 | 0 |
| total | 26 | 26 | 0 |

Claude Code surfaced: prompt_cache_breakpoint is not supported on this model.

The treatment was rolled back immediately. The first 16 post-rollback requests were 16/16 HTTP 200, confirming the errors were treatment-specific.

Same-key miss result without explicit fields

On ordinary append-only traffic with conversation-scoped keys, we observed a 304,776-token Sol follow-up with:

  • same account and physical model;
  • same prompt_cache_key as adjacent turns;
  • unchanged instructions and tools;
  • prior same-key response completed 4.9 seconds before dispatch;
  • previous request: 300,544 / 301,856 input tokens cached;
  • target request: 0 / 304,776 cached;
  • next request: 291,328 / 304,971 cached.

This rules out cache expiry, concurrent publication, key rotation, tool/instruction drift, and an in-flight leader for that event. It matches the intermittent large mid-loop misses discussed here and in #33821/#35925.

Transport and key controls

We also tested two alternatives under natural traffic:

  • persistent Responses WebSocket transport: cache reuse regressed to 75.43%; rolled back;
  • shared stable-prefix keys sharded below the documented ~15 RPM/key guard: warmed reuse remained 86.16%, with max observed key pressure 13 RPM; rolled back.

These results support the existing evidence that a client key or WebSocket connection alone cannot recover the stable ancestor on the ChatGPT subscription backend.

Backend asks

  1. Is prompt_cache_breakpoint intended to be supported on chatgpt.com/backend-api/codex/responses for Sol/Terra/Luna?
  2. If yes, please align the subscription route with the public GPT-5.6 Responses contract for nested prompt_cache_breakpoint and top-level prompt_cache_options over HTTP and WebSocket.
  3. If no, what supported mechanism should Codex use to retain a stable prefix across changing suffixes and independent threads/sessions?
  4. Please make completed same-key, byte-identical prefixes consistently visible across eligible replicas/connections, or document the hidden affinity/scope clients must preserve.

No scripted traffic was sent to Anthropic-backed accounts. The aggregate evidence above contains no prompt text, raw cache keys, session IDs, account IDs, or credentials.

StartupBros · 8 days ago

I prepared the public client-representation patch against current main after the subscription-backend reproduction above.

Branch: https://github.com/StartupBros/codex/tree/feat/gpt56-prompt-cache-controls

Commit: https://github.com/StartupBros/codex/commit/8271903d0a5179db9b3f220acf8231eea4cc150c

OpenAI's collaborator-only PR policy rejected external PR creation, so a maintainer can fetch/cherry-pick it directly:

git fetch https://github.com/StartupBros/codex.git feat/gpt56-prompt-cache-controls
git cherry-pick 8271903d0a5179db9b3f220acf8231eea4cc150c

Patch scope:

  • typed optional prompt_cache_options (implicit|explicit, 30m)
  • typed explicit breakpoint targets, maximum four
  • exact nested {"prompt_cache_breakpoint":{"mode":"explicit"}} injection for message content and structured function/custom-tool outputs
  • HTTP/Responses-WebSocket parity
  • default-off/default-omitted compatibility
  • full-input WebSocket requests when explicit targets are present
  • validation for invalid indexes, unsupported item/block types, and scalar tool output

Validation on rebased current main:

  • just test -p codex-api: 176 passed
  • all codex-api and codex-core test targets compile
  • focused WebSocket request-compatibility test passes
  • scoped API/core Clippy fixes pass
  • independent three-lens review found one blocking structured-output gap; fixed and covered before push

This intentionally does not auto-place breakpoints or change cache keys. It makes the documented public GPT-5.6 wire contract representable; the private ChatGPT subscription endpoint still needs backend acceptance before Codex can enable it there.

NetBr3ak · 5 days ago

These are two different failures and they don't cost the same.

Missing the cache on a prefix that still exists means you pay 1.0 for input
instead of 0.1. Losing the prefix is worse, because rebuilding it is a write,
and writes cost 1.25 times input on the five minute cache and 2x on the one
hour one.

Which is why raising the TTL to survive forking backfires. At 2x you need
1.11 reads per write to break even instead of 0.28. Forking already wrecked
the hit rate, and the longer cache raises the bar.

The number that settles it is reads over writes, per model, with the cache
key and the model held still. The 98.20 against 14.20 above is the only
measurement here that actually does that.