GPT-5.6 builder's guide: same results, $33.27 down to $1.33
- OpenAI's new cost-cutting guide for developers shows a search benchmark score of 84, achieved for $33.27 with the previous top model and $1.33 with this generation's smallest model.
- Six production agent companies each report real metrics: 21% fewer input tokens, 28% less uncached input, and costs down to 1/18th—all from configuration changes, not a new model.
- The official charts also reveal something the text misses: turning reasoning effort all the way off makes the bill go up, not down.
OpenAI has published a GPT-5.6 builder's guide focused on cutting agent costs: which model to choose, how much reasoning effort to set, and how to use three new API switches—all direct configuration changes. Six startups already running agents in production each contributed real-world metrics.
The guide challenges the default way agents have been built: reach for the most expensive flagship model and crank up reasoning. That became the default because only top-tier models could handle long contexts and heavy tool use. With the 5.6 generation, smaller models can think a little longer and match the previous flagship's performance at a fraction of the price.
A roadmap: six levers you can pull today
Saving money works on two levels. The first level is two dials—reasoning effort and model choice—which are simple configuration changes. The second level involves three architectural switches and a caching breakpoint, which change how requests are structured. The table below is your roadmap: the first two rows cover the dials, the last four cover the switches, and each gets its own dedicated section later in this piece.
The first dial: a lower effort level beats last gen's highest
Since GPT-5, each generation has chased the same goal: accomplish more with fewer tokens. GPT-5.6 continues this trend—the Harness (the orchestration layer around the model: how requests are sent, tools are called, and loops are run) is unchanged, yet performance climbs and costs fall.
The guide's most direct example: with the Harness completely fixed, GPT-5.6 Sol at 'Low' reasoning effort outscores GPT-5.5 at 'High' on the Agents' Last Exam benchmark. Since effort is the main cost lever, winning this matchup means the same task just got a whole price tier cheaper. The guide doesn't publish specific scores for this particular comparison.
For a direct comparison you can verify yourself, here are three matchups, all drawn from real data points on the benchmark charts. Old model on the left, new model on the right:
The cost scales on the two charts are very different: the search benchmark costs a few dollars to run completely, while the coding index costs hundreds or thousands—the topics and task complexity aren't comparable. Don't compare dollar amounts across the two charts. Each comparison above is within the same chart.
So what are you actually saving on? It's the wasted effort. Hex, a data analytics company, dropped the model into their existing Harness and found the lowest effort setting gave them the best results they'd ever seen:
We put GPT-5.6 into our existing Harness, and the low reasoning setting gave us the best results we've had. It knows when the data just isn't there, doesn't chase dead ends, and gets to the right answer with fewer tokens.
Izzy Miller, Head of AI Research at Hex
That phrase—"knows when the data isn't there"—is the key. Older models would rephrase a search query and keep digging when they couldn't find something, paying for every tool result that came back as input tokens. A model that knows when to stop saves exactly those wasted cycles.
Lowering Effort Works, But Turning It Off Completely Costs More
Lowering the effort level saves money. So wouldn't turning it off entirely save even more? Looking at the actual data points on OpenAI's charts, the answer is no.
The dial below lets you explore this: pick a reasoning level, and watch the cost and score for all four models change. The cost bars are scaled so GPT-5.5 at Xhigh equals the full length of the track ($33.27 on the Search benchmark).
Now move the dial all the way to the left. You'll see something counterintuitive: turning reasoning off does not save money. There's evidence for this on both official charts:
- Sol on the Search benchmark: With reasoning off, it costs $1.97 for a score of 69.67. At the lowest effort setting, it costs just $0.50 for a score of 65.32. So turning reasoning off didn't save money—it cost 3.9x more for only 4.3 extra points.
- Luna on the Coding Index: With reasoning off, it costs $123.66 for a score of 37.30. At the lowest effort setting, it costs $74.84 for a score of 42.40. This one is both more expensive and worse—65% more money for 5.1 fewer points.
There's a similar inflection point at the other end. On Search, Luna going from "Xhigh" to "Max" sees its bill rise from $1.33 to $1.42, but its score drops from 84.04 to 83.25. Maxing out the dial doesn't necessarily help either.
If the model isn't allowed to think, it has to stumble toward an answer by making more tool calls and going around in circles. And every tool result that comes back is billed as an input token. Thinking costs money, but it buys "fewer wrong turns"—a deal that usually pays off on hard tasks.
The right way to tune effort is to start from the bottom and work your way up, watching cost and score move together until you hit the sweet spot—not to start from the top and cut downward. The lowest effort setting is usually the best value. The far-left setting, completely off, doesn't pay off on either of these charts.
The second dial: smaller models can save 25x
Once you've adjusted the effort dial, the next one is model choice. GPT-5.6 comes in three sizes: Sol (flagship), Terra (mid-size), and Luna (small).
In the past, the smaller models were only good for edge cases—they couldn't handle long contexts or heavy tool use, and they'd fall apart once the task chain got long. That's changed with this generation, thanks to test-time compute.
This lets the model think a bit longer before answering. The thinking time is compute, and compute is money. It's the difference between giving a student an extra ten minutes to check their work versus swapping in a smarter student. The smaller models take the first path; the model itself doesn't change.
The result is that Luna and Terra can often match GPT-5.4 or GPT-5.5 performance at a tiny fraction of the cost. The guide's headline comparison comes from BrowseComp, a benchmark that tests the ability to unearth obscure facts:
Hypha, a document agent company, reported a different angle:
Luna retains 98% of GPT-5.5's extraction accuracy at 1/18th of the cost. This makes high-quality document understanding affordable for our agents, and at this price, it becomes viable in far more scenarios.
Serhii Shchoholiev, Head of Agent Engineering at Hypha
Where Do Smaller Models Fit in a Workflow?
There are three types of tasks they're best suited for: high-volume tasks, latency-sensitive interactions (where users are waiting), and steps that repeat frequently in an agent flow.
The guide's example is a legal tech company. Before its agent can analyze documents, it has to parse handwritten memos into text. This parsing step doesn't require judgment, but previously it used the flagship model along with the rest of the flow. By isolating it and switching to Terra or Luna, they saved real money, while the step that actually requires judgment continued to use Sol.
These two charts were run by OpenAI. They include competitor models like Claude Fable 5, Claude Opus 4.8, Claude Mythos Preview, and Gemini 3.1 Pro Preview. On the BrowseComp chart, competitors appear only as horizontal reference lines, showing their scores (Claude Mythos Preview 87.9%, Gemini 3.1 Pro Preview 85.8%, Claude Opus 4.8 84.4%) without corresponding costs, so you can't directly compare their prices to the ones above. Our charts here only show the relationships between GPT-5.6 models, their effort levels, and their costs.
Break down your workflow and find the mechanical steps that don't require judgment—parsing, extraction, categorization, format conversion, translation—and assign them to Terra or Luna. Keep the judgment-heavy parts on Sol. Using the same model for the entire chain is a habit left over from the previous generation.
Three architectural switches: two of them nearly triple performance
Once you've maxed out the model and effort dials, there's not much more to squeeze there. The remaining savings come from architecture—specifically, what your agent stuffs into its context on each turn.
The guide organizes its efficiency methods into three categories, and stresses that GPT-5.6 was trained end-to-end with these three things in mind. The model understands how to work with them natively; you don't need to build external tricks to coax it into behaving:
Keep reasoning across turns (Persistent Reasoning), and use Native Compaction to shorten long conversations. The model doesn't have to rethink everything each turn, and it won't lose thread if the context gets trimmed.
Native multi-agent orchestration: The main agent delegates independent chunks of work, several subagents work simultaneously, and the results are gathered at the end.
Programmatic Tool Calling: Move filtering, aggregation, and orchestration—actions that don't require intelligence—outside the model's context window. The model's tokens are reserved for judgment calls.
The guide provides a concrete example of how much these three together can help. On the ARC-AGI-3 benchmark, GPT-5.6 Sol scores 13.3% with a standard Harness. Simply turning on "Persistent Reasoning" and "Compaction" jumps the score to 38.3%, while also producing about 6x fewer output tokens:
The score nearly tripled, yet the token count dropped by five-sixths. Both happening at once shows exactly what you're saving: the wasted cycles of "rethinking" and "reorganizing" the context.
On 5.6, all three of these are configuration changes—no model change, no Harness rewrite needed. The next four sections break down where to change each setting, what values to use, and when you shouldn't turn something on.
Switch 1: Stop the Model from Rethinking Everything
The first switch addresses the most expensive waste in long tasks: the model redoing work it's already done.
Persistent Reasoning: Bringing Last Turn's Thinking into This Turn
Previously, a model's chain-of-thought was discarded after each response. The next turn, it could only see the conversation history—not what it was thinking a moment ago—so it would reason from scratch again. GPT-5.6 supports carrying reasoning entries from previous turns into the next context. The parameter is reasoning.context:
| Value | Behavior | Default for |
|---|---|---|
current_turn | Only this turn's reasoning is available; previous reasoning isn't brought into the next sampling. | Models before GPT-5.6 |
all_turns | Brings prior matching reasoning entries into the next sampling. | GPT-5.6 family |
auto | Follows the model's default; omitting this field is the same as auto. | — |
Two things to watch out for. First, all_turns only works if this request can access the previous responses—either by chaining with previous_response_id or by replaying the full response history. On your very first request, there's no difference between the two settings, since there's no prior reasoning to carry over. Second, it only provides continuity: those reasoning entries remain encrypted and unreadable. The API doesn't return reasoning text; you can't see what the model was thinking.
Native Compaction: Automatic Packing at a Threshold
Conversations only get longer. Native compaction works by setting a line: include context_management in your request, with a compact_threshold (say, 200,000 tokens). When the rendered context exceeds this line, the server automatically compacts, emitting a "compaction entry" in the same response stream, then truncating the earlier context and continuing to reason. No extra API call is required from you.
The easiest thing to misunderstand here is the nature of the compaction entry. It's opaque and unreadable—the official docs describe it as "opaque and not intended to be human-interpretable." This is not the same as "have the model write a summary of the conversation." A summary is natural language; what gets written and what gets dropped is up to the model's discretion in the moment. A compaction entry is a structure the model learned to encode and decode during training, carrying the previous state and reasoning along in fewer tokens without losing anything.
It's like vacuum-packing a room full of files. You can't open the bag or see what's inside, but when the model opens it next turn, it knows exactly what happened before. Writing a summary, by contrast, is like asking a person to hand-copy a list of key points—anything that person thinks isn't important is gone forever.
while keep_going:
response = client.responses.create(
model="gpt-5.6",
input=conversation,
store=False,
context_management=[{"type": "compaction", "compact_threshold": 200000}],
)
conversation.extend(response.output)
conversation.append({"type": "message", "role": "user",
"content": get_next_user_input()})
store=False is used to meet Zero Data Retention (ZDR) requirements.There's also a standalone /responses/compact endpoint for when you want full control over timing. You send in an entire context window, and it returns a compacted window, fully stateless. There's a hard rule for using it: pass the returned window verbatim to your next call—don't trim it yourself, because besides the compaction entry, that window also contains entries from the last turn that need to be retained.
Conversely, if you're using server-side compaction chained with previous_response_id, don't manually trim entries either. Only in the stateless input-array mode can you drop everything before the most recent compaction entry, making the request body smaller and reducing tail latency.
For long tasks (long-running coding agents, deep research), make sure reasoning.context is set to all_turns—it's the default on 5.6, but if you migrated code from earlier models and hardcoded current_turn, you've effectively disabled this switch. For compaction, add context_management to your request with a compact_threshold.
Switch 2: Let the Model Write Code to Filter Data
Long tasks are no longer redoing work, but there's another, more common waste: the context window getting bloated with intermediate results.
Agent work actually comes in two flavors. One requires judgment—is this contract problematic, should I keep digging? The other is pure data handling—filtering, merging, sorting, deduplicating, summing. The problem is, in the past, both had to happen inside the model's context.
Here's the guide's example: Your agent pulls back 100 files, needs to filter them by date, and then find the relevant transactions among them. The old way, all 100 files go into the context, and the model reads through them one by one. Three bad things happen simultaneously: it's slow, it's expensive, and the more cluttered the context gets, the more confused the model becomes (this phenomenon is called "context rot").
Programmatic Tool Calling takes a different approach: the model writes a bit of JavaScript to orchestrate those tools directly. This code can make independent calls concurrently, write loops and conditionals, and keep all intermediate results inside OpenAI's managed runtime. Only the final, filtered result is handed back to the model.
Where Does That Code Run?
It runs in a brand-new, isolated V8 runtime, completely clean on every execution. The environment's boundaries are strictly defined:
- What's there: JavaScript with top-level
await; access to the tools you've opened up in this request; the ability to output results withtext(...)orimage(...). - What's not there: Node.js, package installation, network access, a general file system, subprocesses, console, and any state between executions.
- Your functions still run on your own server: When the program hits your tool, it pauses, sends the call out to you, and only continues after you've run it and returned the result with the original
callerfield intact. A single run can pause many times.
You decide which tools the code is allowed to call. Each tool gets an allowed_callers annotation:
| Value | Behavior |
|---|---|
Omitting, or ["direct"] | Only callable directly by the model. |
["programmatic"] | Only callable by code inside a program. |
["direct","programmatic"] | Both ways work. |
Tool types that can be called from code: regular functions and custom tools, MCP tools, apply_patch, local and hosted shells, and the code interpreter. MCP approval policies still apply; if your setup requires approval, the program will pause and wait for you to approve.
{
"type": "function",
"name": "get_inventory",
"parameters": {
"type": "object",
"properties": { "sku": { "type": "string" } },
"required": ["sku"],
"additionalProperties": false
},
"output_schema": {
"type": "object",
"properties": {
"sku": { "type": "string" },
"available_units": { "type": "number" }
},
"required": ["sku", "available_units"],
"additionalProperties": false
},
"allowed_callers": ["programmatic"]
}
parameters describes the input. output_schema describes the JSON shape this function returns. With both clearly defined, the model can write code that reliably accesses fields, rather than guessing.When Not to Use It
This switch isn't always a win. The official docs include a helpful decision table, based on whether the control flow for this segment is predictable and whether code can actually shrink the result:
| Task shape | Which approach to use |
|---|---|
| A single query or a single action | Direct call |
| Multiple results, where code can filter, join, sort, dedupe, aggregate, or validate | Programmatic call (provided the program can return a smaller, structured result) |
| Dependent calls, but the data flow is predictable | Programmatic call (provided the code can derive later parameters and has clear failure behavior) |
| Adaptive search, semantic judgment where each result influences the next decision | Direct call |
| Write operations, actions requiring approval | Default to direct calls, to maintain a clear authorization boundary. |
| Final citation checking, native artifact validation | Direct call, unless the program fully retains the original outputs and validates them item by item. |
When both modes are enabled, you also need to tell the model which segment uses which path. Telling it to "use Programmatic Tool Calling efficiently" doesn't establish a boundary. The official docs offer a copy-paste template:
<tool_orchestration> Use Programmatic Tool Calling for [bounded stage] using only [eligible tools]. Run independent calls concurrently when safe. Use only documented tool input and output fields. Process and reduce the intermediate results, then emit exactly [program result shape], including the evidence needed for the final answer. Stop when [condition] is met. Retry transient failures at most [R] times. Do not repeat completed calls or perform side-effecting actions. If a required result is still missing, return a clear structured failure. Use direct tool calls for [semantic judgment, approval, or final validation]. </tool_orchestration>
Rogo, a financial research company, applied this to the chain of pulling financial reports, coordinating tools, and calculating numbers:
In financial research, the difficulty lies in reliably pulling documents, coordinating tools, and getting the numbers right. In our benchmarks, GPT-5.6 with Programmatic Tool Calling achieved the same scoring standard as before, while using 21% fewer input tokens. That's the difference between "an agent that can talk about financial research" and "an agent that can actually complete financial research."
Alex Wang, Applied AI Team at Rogo
Add the programmatic_tool_calling managed tool to your request, then add allowed_callers to each tool and output_schema to your functions. If you have both modes on, use the <tool_orchestration> template above to make the boundary explicit. Don't leave write operations or approval-requiring actions to the code.
Switch 3: Main Agent Delegates Parallel Work
While deterministic work can be moved out, splittable work should also happen simultaneously.
If a task can be divided into independent chunks, a single agent has to do them sequentially. Multiple agents can work at the same time. GPT-5.6 builds this orchestration into the API: The main agent (called /root) handles task decomposition, delegation, waiting for results, and synthesizing a final answer. Your application doesn't need to write any orchestration logic.
Qualia fed a pile of open-ended research questions to a team of agents, and GPT-5.6 Sol got it right on the first try. It's a clear step up from GPT-5.5 and faster than almost any model we've tested, which quickly made it our default OpenAI model.
E Chi, Founder of Quadrillion
GPT-5.6 is the best orchestrator we've seen from OpenAI. We gave it six requirements at once (write, build, and explain all six), and it never dropped a thread or lost quality.
Jon Bell, Co-founder & CPO at Obvious
There are three distinct benefits here: Parallel execution saves wall-clock time; separate contexts mean each subagent gets a well-defined task, independent work doesn't interfere in the same context, and accuracy actually goes up; and model-driven coordination means spawning, messaging, and waiting are all handled by the model itself.
How to Enable and Manage It
| What to change | How |
|---|---|
| The switch | multi_agent.enabled: true; currently in beta, requires the responses_multi_agent=v1 header |
| Concurrency limit | max_concurrent_subagents; default is 3, which OpenAI recommends for most cases. This counts the total number of concurrently active subagents in the tree (including grandchildren), not the root agent. |
| Limits | Tree depth and total subagent count have no fixed limits. |
| When to delegate | Add a developer message. It combines with your instructions to the root agent. |
The model has its own judgment about "how many to spawn and when," but this is something you can control. The official docs offer two ready-made messages, one conservative and one aggressive. Just paste them into your prompt:
Conservative: only spawn when the user explicitly asks Do not spawn subagents unless the user explicitly asks for subagents, delegation, or parallel agent work. Aggressive: proactively delegate when parallelism would clearly help Proactive Multi-agent delegation is active. Use subagents when parallel work would materially improve speed or quality.
During execution, you'll see six types of coordination actions in your output. These are managed server-side, so your application doesn't need to execute them or return results for them:
| Action | Purpose |
|---|---|
spawn_agent | Create a subagent and assign it its first task. |
send_message | Message an existing agent without starting a new turn. |
followup_task | Add a task to a non-root agent, starting or resuming its turn. |
wait_agent | Wait for activity in one's own mailbox. |
interrupt_agent | Interrupt an agent's active turn without deleting its context. |
list_agents | Get the current state of the entire tree, including each agent's status and last task message. |
Four Cases Where You Shouldn't Use It
There are four clear anti-patterns for this switch:
- Each step directly depends on the previous one—it's an ordered reasoning chain that can't be broken up.
- The task is small enough to finish in a single run—the overhead of delegation outweighs the work itself.
- Several agents would contend for the same mutable resource—frequently writing to a single shared state means parallelism just causes conflicts.
- You need a fixed, deterministic execution graph—if the model does the scheduling, the execution path isn't fully predictable.
Also, if the whole task is bottlenecked by a single slow external operation, adding more agents won't make it faster.
Enabling Multi-Agent Comes with Side Effects
The official docs list a few limitations, and the first one directly affects what we covered in the previous section:
- Compaction is automatically enabled. Setting
multi_agent.enabledtotrueimplicitly turns on server-side compaction, even if you haven't configured acontext_managementfield. Compaction applies independently to the root agent and each subagent, preserving each of their contexts. You can still explicitly set acompact_thresholdto override the default. - The standalone
/responses/compactendpoint is unavailable. If you were managing compaction timing yourself, that approach isn't supported in multi-agent mode. reasoning.summaryis not supported.max_tool_callsis not supported. If you were relying on this field to cap tool calls, you'll need another strategy before enabling multi-agent.
The "ultra" tier you see in ChatGPT runs on this exact mechanism. On the BrowseComp chart, it occupies its own point: GPT-5.6 Sol Ultra at Max effort scores 92.18, at a cost of $12.17—1.8 points higher than Sol alone at Max (90.36), for roughly double the bill.
Enable multi_agent.enabled, leave max_concurrent_subagents at its default of 3, and use the developer message above to define when it should delegate. First, confirm your task can actually be split into independent chunks. If not, turning this on just spends tokens on coordination.
The Last Switch: A Misplaced Cache Breakpoint Costs Money
The first three switches are pure wins. This one is different—it can actively lose you money.
The guide has two good pieces of news about caching: the entire model family now has a cache lifetime of at least 30 minutes, and cache breakpoints can now be set deterministically within the context. Ploy shared their real-world test:
We added a cache breakpoint and a key based on workspace to a shared 29,000-token prompt, and our uncached input dropped by 28%. The 30-minute cache window is also a big unlock: our agents can reuse the same context across multiple runs without loading from scratch every time.
Lorenzo Gentile, AI Engineer at Ploy
But a table in the official docs reveals something the guide leaves out: GPT-5.6 changed how cache matching works.
| GPT-5.6 and later | Earlier models | |
|---|---|---|
| Matching | Exact match only, at breakpoints | Best-effort automatic reuse of whatever prefix matches |
| Explicit breakpoints | Supported (implicit caching still applies) | Not supported, fully automatic |
| Minimum cacheable prefix | 1,024 tokens | 1,024 to 2,048 tokens, depending on model |
| Cache write fee | 1.25x the uncached input price | No extra fee |
| Lifetime | Exactly 30 minutes, set with prompt_cache_options.ttl | Varies by model |
By default, the system places an implicit breakpoint at the most recent user or tool message and does not automatically search backwards for the longest matching prefix like older models did. The three-tier pricing can be summarized in three lines:
Put those two facts together, and you can see how you'd lose money. Imagine your prompt is "a stable few-thousand-word instruction + a timestamp + the user's question this turn." With nothing configured:
Wherever you mark the breakpoint, that content block plus everything rendered before it becomes the reusable prefix. So the rule is simple: find the part of your prompt that never changes, and draw the breakpoint right after its last character.
{
"model": "gpt-5.6",
"prompt_cache_key": "support:knowledge-base-v1",
"prompt_cache_options": { "mode": "explicit" },
"input": [
{
"type": "message",
"role": "developer",
"content": [
{
"type": "input_text",
"text": "Follow the shared support policies and reference material...",
"prompt_cache_breakpoint": { "mode": "explicit" }
}
]
}
]
}
mode: "explicit" turns off the default implicit breakpoint, so that changing tail doesn't get written to the cache again. Note: if you set explicit mode but don't add any explicit breakpoint, this request doesn't use the cache at all and incurs no write fee.You can set multiple breakpoints, which is useful when different parts of your prompt change at different frequencies (shared instructions are stable, reference material updates occasionally). This way, each request can reuse the longest unchanged prefix. But there are two limits to keep in mind: you can write a maximum of 4 new caches per request (if you have more than 4 breakpoints, only the last 4 get written; in implicit mode, the breakpoint at the latest message takes one of those slots), and you can look back a maximum of 50 recent breakpoints when reading. When multiple breakpoints match, the server reads from the longest matching prefix.
How to choose among the three modes: Implicit (default) is for conversational patterns where you're appending new content and the history before it is static. Implicit plus explicit breakpoints is for when both a shared prefix and a growing history are worth reusing. Explicit only is for when your prefix is stable, but everything after it changes every time and almost never gets reused.
One more thing related to latency: assigning the same prompt_cache_key to related requests increases the chance they land on the same inference machine, which is more likely to have the prefix already written. That lowers latency too.
Put prompt_cache_breakpoint on the last content block of your stable prefix, and use a consistent prompt_cache_key. Double-check that nothing before the breakpoint ever changes. A timestamp, random ID, or username mixed in means you're paying 1.25x to write a cache that nobody will ever read. Prefixes shorter than 1,024 tokens never enter the cache at all.
Parameter Cheat Sheet for All Six Changes
The whole article boils down to this table.
| What to change | Where | Value / Default | Official result |
|---|---|---|---|
| Reasoning effort | reasoning.effort | Work your way up from the lowest setting, not down from the top | Low beats prev-gen High |
| Smaller model | model | Use Terra/Luna for mechanical steps, Sol for judgment | $33.27 → $1.33 in the same score band |
| Persistent Reasoning + Native Compaction | reasoning.contextcontext_management | all_turns (5.6 default) / current_turn / auto{"type":"compaction","compact_threshold":200000} | Both on: 13.3% → 38.3%, ~6x fewer output tokens |
| Programmatic Tool Calling | Add the programmatic_tool_calling tool + allowed_callers on each tool | direct / programmatic / both | 21% fewer input tokens |
| Multi-agent | multi_agent.enabled | true; max_concurrent_subagents default 3 (beta) | Ultra tier scores 92.18 on BrowseComp |
| Cache breakpoint | prompt_cache_breakpoint + prompt_cache_key | Pin it to the end of your stable prefix; ttl only supports 30m | 28% less uncached input |
Limitations Only in the Official Docs
- A cache prefix shorter than 1,024 tokens never enters the cache. This number applies to the entire rendered prefix up to the breakpoint, not just the block you marked.
- Keep traffic per
prompt_cache_keyto around 15 requests per minute. Higher rates will drop your hit rate. For high traffic, use stable, deterministic keys and shard across them. - Each reuse refreshes the 30-minute lifetime, and the refresh doesn't incur a write fee. The 30 minutes start from the moment of writing and re-arm each time it's reused.
- Spawning subagents burns extra tokens. For tasks that can't be split, or that frequently write to shared state, enabling it just spends money on coordination.
- The Programmatic Tool Calling sandbox has no network, no file system, no package installation, and leaves no state behind after execution. The code can only interact with the outside world through the tools you've made available in that request.
- You can write at most 4 new caches per request and look back at most 50 recent breakpoints. If you set more breakpoints, only the last 4 get written.
- Enabling multi-agent implicitly turns on server-side compaction, and the
/responses/compactendpoint,reasoning.summary, andmax_tool_callsare no longer supported. This is the easiest one to miss: you think compaction isn't on, but it is.
Troubleshooting Cache Misses
| Symptom | Check |
|---|---|
cached_tokens is 0 | Is the prefix up to the breakpoint at least 1,024 tokens? Has a previous request ever written that same prefix? Are related requests using the same prompt_cache_key? |
| Writing to cache on every request | Is there a timestamp, changing user input, or tool-call history before the breakpoint? Move the explicit breakpoint to the end of your stable prefix. |
| Both read and write are non-zero | In implicit mode, this is normal (reading the old prefix and writing the newly appended content to the latest breakpoint). If you don't want to cache new content, switch to explicit-only. |
| Using explicit mode but no hits | Confirm at least one content block has prompt_cache_breakpoint and that the prefix up to that marker meets the 1,024-token minimum. |
The guide's closing thought sums up the whole table: the work that used to require a frontier model at every step can now be done with a smaller model, a tuned reasoning effort, and a few architectural choices—achieving the same or better results at a fraction of the cost.
OpenAI Just Shared 6 Levers That Slash Your Agent Bill by 25x
Six production agent startups provide real numbers. Here's a visual guide to six levers you can pull today.
↓ One page to read · One interactive chart included
OpenAI's "Builder's Guide" is a manual for lowering your agent bill. The old way to build an agent was to reach for the most expensive flagship model and max out reasoning, because only the flagship could handle long tasks. GPT-5.6 has three tiers—flagship Sol, mid-size Terra, small Luna—and the smaller models can now think longer and match the flagship's output for a fraction of the price.
The first instinct to save money might be to turn off "thinking." OpenAI's own charts show the opposite: disabling reasoning never made the bill lower.
The right direction is to start from the lowest effort and go up, watching cost and score together, and stop at the sweet spot.
Beyond effort and model size, GPT-5.6 has three things trained directly into the model: keeping reasoning across turns, moving data-shuffling work into code, and delegating splittable tasks to parallel subagents. All three are configuration changes—no model swap, no Harness rewrite.
The six levers come in two layers: two dials (reasoning effort, model size) and four config switches. All are configuration changes—no model swap, no Harness rewrite.
✔ For long tasks, let the model remember what it thought earlier, instead of starting over each turn.
✔ When a tool returns a huge batch of data, have the model write code to filter it externally, and only send back the result.
✔ Keep your stable content at the very beginning of your request so it can be cached and reused.
✘ Don't put timestamps or random IDs into the part of the prompt you want cached—you'll be paying to write a cache nobody reads.
Xiaohu's agent is running around the clock
But the bill grows faster than the results
Reasoning off
$1.97
Lowest effort
$0.50
Same search task
No thinking means more tool calls, and tool calls cost money
Prev-gen flagship
$33.27
This gen's small model
$1.33
Same score, around 84
25x CHEAPER
Score barely changed. Small tasks, small model.
Same test, same model
13.3% → 38.3%
It also wrote 6x less
- × Remember what it thought last turn
- × Write code to filter data
- × Run agents in parallel
The cache breakpoint is a trap too
Breakpoint at end ✕
Re-writes every time
1.25x price
Breakpoint at stable spot ✓
Cache hit
0.1x price
Six levers, all just config
Numbers are from OpenAI's own testing. Re-test in your own environment before you deploy.
ENDXiaohu Explains · best.xiaohu.ai
Members can copy or download the full Markdown, and let their AI subscribe and ask.
Found this useful? Leave your email — every new explainer, the moment it's out. Unsubscribe anytime.