Control Reasoning Effort LLM APIs in Production
Control reasoning effort LLM APIs across OpenAI, DeepSeek, and Anthropic. Practical routing rules to cut cost and latency without losing accuracy.

In this article
- 1.Why Maximum Reasoning Effort Is a Production Anti-Pattern
- 2.OpenAI o-Series: The reasoning_effort Parameter
- 3.When to pick each tier
- 4.DeepSeek R1: Bounding the Hidden Reasoning Trace
- 5.Practical DeepSeek configuration
- 6.Anthropic Claude: Allocating the Extended Thinking Budget
- 7.Why the budget shape is better for some workloads
- 8.Cross-Provider Comparison: Reasoning Control Knobs
- 9.How LLM Reasoning Effort Drives Cost, Latency, and Quality
- 10.Decision Rules: Routing Tasks to the Right Effort Tier
- 11.What Comes Next for Automatic Effort Selection
Reasoning models default to maximum effort on every prompt. When a user asks a reasoning-tier model to summarize one paragraph, the model still spends hundreds or thousands of tokens on an internal chain of thought before it writes a single visible word. You pay for those tokens, and your user waits for them. To control reasoning effort LLM behavior at scale, you have to stop treating "thinks hard" as a fixed model property and start treating it as an explicit API knob. OpenAI, DeepSeek, and Anthropic each expose that knob in a different shape, and the default value is rarely the one you want in production.
Stay in the loop.
Get the latest posts and exclusive content delivered to your inbox.
Join 3 readers. No spam. Unsubscribe in one click, anytime.
This is the part of reasoning-model deployment that the training papers skip. Reinforcement learning with verifiable rewards explains why these models can reason. The deployment question is different: given a request, how much reasoning should the model be allowed to do, and how do you enforce that limit in the API call?
Why Maximum Reasoning Effort Is a Production Anti-Pattern
The cost asymmetry is the core problem, and it is externally measurable. Reasoning tokens are billed at output-token rates but produce zero visible output for the end user. A request that should cost a fraction of a cent can balloon when the model spends several times more tokens reasoning than it spends on the visible answer. That ratio is observable in every API response that exposes a reasoning-token count.
Latency follows the same shape. Chain-of-thought tokens generate before the visible answer, so the user waits on reasoning they will never read.
The first generation of reasoning models had no off switch. DeepSeek-R1 emitted verbose reasoning traces on every prompt, including trivial ones, with no parameter to suppress them. That is fine for a research artifact. It is expensive for a production API.
Defaulting to maximum effort assumes every request is hard. Most production traffic is a mix: classification, extraction, and formatting on the easy end, with math, multi-step planning, and code generation on the hard end. Treating them all as hard wastes budget on the easy majority where reasoning adds little.
OpenAI o-Series: The reasoning_effort Parameter

reasoning_effort is an ordinal label that indirectly controls how many tokens the model spends on internal chain-of-thought. The parameter accepts discrete values, minimal, low, medium, and high (availability varies by model), passed at the top level of the chat completion request on the o-series (o1, o3, o4-mini) and the GPT-5 family, as documented in the OpenAI reasoning guide. The mapping from low to high is a non-linear, model-specific curve, and the same label produces very different token counts depending on which model you call.
Three things most teams miss:
- The
reasoningresponse block is your best observability tool, and almost nobody logs it. Every response includes areasoningobject showing the actual reasoning-token count for that call. Without it, you are tuning effort tiers by guesswork. Instrument it from day one so you can see what each tier actually costs on your traffic. - Calibrate effort on your own data, not on the vendor default. Take 50 to 100 real production prompts, run each at
low,medium, andhigh, and plot task accuracy against reasoning-token spend. You will find a knee where marginal tokens stop buying accuracy. That knee is your production default. Teams that skip this step inherit a default optimized for benchmark scores, not their unit economics. - The same label means different things on different model sizes.
highon o3-mini andhighon o3 consume vastly different token counts because the underlying models reason at different depths. A tier that was cost-justified on the smaller model can bleed budget on the larger one. Recalibrate whenever you change model size.
Practical constraints:
reasoning_effortonly applies to models in the reasoning family. Passing it to a non-reasoning model is typically ignored rather than raising an error, though behavior may vary by model and SDK version.- On the o-series,
temperature,top_p, and several other sampling parameters behave differently or are unsupported. Check the docs for the specific model. - Pricing is per token regardless of effort tier, so the cost lever is purely the number of reasoning tokens the model emits. Current prices are on the OpenAI pricing page.
When to pick each tier
minimalorlow: classification, sentiment analysis, formatting, JSON extraction, simple Q&A where latency matters more than marginal accuracy.medium: ambiguous tasks, multi-document synthesis, summarization of dense material, standard code review.high: competition math, multi-step logical proofs, novel code architecture, debugging subtle issues, agentic tool-use chains where one wrong step cascades.
DeepSeek R1: Bounding the Hidden Reasoning Trace

DeepSeek gives you something OpenAI deliberately hides. The R1 response object splits into two fields: content for the visible answer and reasoning_content for the chain of thought. You see the full hidden reasoning trace on every call, which makes R1 the best available model for understanding how reasoning tokens actually behave in your traffic. OpenAI hands you an opaque token count. DeepSeek hands you the text.
That observability is also a warning sign. R1 has no clean off switch. The base API does not expose a dedicated reasoning-budget parameter. The original release emitted a verbose trace on every prompt regardless of complexity, and the only lever you get is max_tokens, which caps total output including reasoning. When max_tokens is your only budget lever, reasoning eats the visible-answer budget. Set max_tokens to 2,000, the model spends 1,800 on reasoning, and your user sees a truncated 200-token answer.
This makes R1 a poor default for mixed-traffic endpoints. Route to DeepSeek-V3 for anything that does not explicitly need chain-of-thought, and reserve R1 for tasks where the reasoning trace earns its token cost.
Pricing compounds the problem. DeepSeek bills reasoning tokens as output tokens, with separate rates for cache hits and misses on reused prefixes. The DeepSeek pricing page documents the full rate structure, and a direct R1 versus o3-mini comparison shows the per-token tradeoffs against OpenAI's equivalent tier. Prompt caching on long system prompts can offset some of the reasoning cost if you structure prompts to reuse prefixes.
If you serve R1 through AWS Bedrock, the interface changes. Bedrock exposes the model through an inferenceConfig block where max_tokens bounds reasoning. The Bedrock DeepSeek parameters page documents the available fields.
Practical DeepSeek configuration
- Route easy tasks to DeepSeek-V3. If a task does not need chain-of-thought, do not pay for it.
- Watch the reasoning-to-content ratio. Log
reasoning_contentlength againstcontentlength. If reasoning eats more than half the budget on easy tasks, your routing is wrong. - Cache aggressively. Prompt caching discounts reused prefix tokens, which compounds with long system prompts.
Anthropic Claude: Allocating the Extended Thinking Budget
Anthropic takes the most explicit approach to reasoning control. Instead of an ordinal effort level, you allocate a token budget directly. Claude 3.7 Sonnet and later models support a thinking block in the API request with two fields: type: "enabled" and budget_tokens, the maximum number of tokens the model can spend on internal reasoning before it must emit the visible response.
The mechanics matter:
budget_tokensis a hard ceiling, not a target. The model can stop reasoning earlier if it is confident.- The total
max_tokensparameter must be greater thanbudget_tokens. The model spends up tobudget_tokensthinking, then continues generating the visible answer within the remaining headroom. Set them equal and the model has no room to answer. - There is a minimum floor on
budget_tokens, typically in the low thousands. Check the current docs for the exact threshold. You cannot allocate 50 tokens of thinking. - Thinking tokens are billed as output tokens.
The Anthropic extended thinking guide covers the request shape and constraints in full. The feature shipped with Claude 3.7 Sonnet, announced in Anthropic's February 2025 release.
Why the budget shape is better for some workloads
Anthropic's approach is more legible than an effort enum. You can reason about it in dollars before the call: if output tokens cost a known amount per million and you allocate 4,000 thinking tokens, you know the upper bound on the thinking surcharge for that request. OpenAI's reasoning_effort=high does not give you that bound. You find out how much it cost when the response arrives.
The tradeoff is that the budget is set per call, not learned from the input. You still need a router if you want the budget to scale with task difficulty.
Cross-Provider Comparison: Reasoning Control Knobs
| Provider | Parameter | Control Type | Observability | Enforcement |
|---|---|---|---|---|
| OpenAI | reasoning_effort | Ordinal (low/med/high) | Token count only | Soft, model sets depth |
| DeepSeek | max_tokens | Hard, shared with answer | Full reasoning text | Hard ceiling, shared |
| Anthropic | budget_tokens | Hard, separate | Thinking block visible | Hard ceiling, separate |
Instrumentation closes the loop. Log reasoning-token counts per request using the OpenAI reasoning block, DeepSeek's reasoning_content field, and Anthropic's thinking block, then set spend alerts on abnormal reasoning-to-content ratios. Tracking that ratio trend over time catches model drift, since a silent model update can shift your token economics without warning.
How LLM Reasoning Effort Drives Cost, Latency, and Quality
Cost, latency, and quality do not scale linearly together. Provider-specific pricing creates breakpoints the vendor docs never surface.
The marginal accuracy curve flattens before the cost curve. Per-token pricing stays flat whether the model is on reasoning token 200 or 4,000. Accuracy does not. The chain-of-thought token consumption study measures reasoning length against task performance and finds gains saturate, sometimes degrade, past a task-specific threshold. The last 2,000 tokens cost the same as the first 2,000 but buy a fraction of the accuracy.
Time-to-first-visible-token has a reasoning-length cliff, not a total-token cliff. Reasoning tokens generate during prefill, before visible output. The LLM inference performance analysis shows why latency does not scale linearly with token count: prefill and decode have different throughput, so doubling reasoning can more than double the wait before the user sees a word.
Cache-hit pricing breaks naive per-provider comparisons. DeepSeek discounts reused prefix tokens at cache-hit rates, not full output rates. A reused system prompt shifts the effective per-token cost in ways a list-price spreadsheet misses entirely.
Decision Rules: Routing Tasks to the Right Effort Tier
The single most effective lever to reduce reasoning model token cost is task routing. But routing tables that ignore provider differences give bad advice. OpenAI uses an ordinal label that indirectly caps spend. DeepSeek uses a shared hard ceiling where reasoning eats answer budget. Anthropic uses a separate budget where thinking is capped independently. The same task maps to different cost outcomes on each.
| Task type | OpenAI | DeepSeek R1 | Anthropic |
|---|---|---|---|
| Classification, extraction, formatting | low or skip reasoning model | Route to V3, not R1 | Skip thinking |
| Code review, dense summarization | medium (safe indirect cap) | Risky: reasoning may truncate answer | Small budget_tokens (2K to 4K) |
| Math, logic, multi-step planning | high | R1 justified, cap max_tokens generously | Larger budget_tokens (8K+) |
| Agentic tool chains | high with monitoring | Avoid: unpredictable trace length | Explicit budget_tokens per step |
Code review on OpenAI at medium is safe because the label indirectly controls spend without threatening the visible answer. The same task on DeepSeek R1 risks truncation because reasoning and output share one max_tokens ceiling. On Anthropic it is the safest of the three because the thinking budget is separate from answer headroom.
The task-based LLM routing overview covers the architecture patterns for using a cheap classifier model to route to expensive reasoning models only when needed.
Rules of thumb across all three providers:
- Default to cheap, not to smart. Start on the lowest tier that works. Raise effort only with evidence the current tier is failing.
- Measure the reasoning ratio. Log reasoning tokens against visible content on every provider. Above 3:1 on easy tasks means your routing is wrong.
- Cap budgets on user-facing endpoints. Never let the model reason indefinitely. Accept slightly lower accuracy for predictable latency.
- Expose overrides for high-stakes work. Where correctness matters more than latency, make the higher tier an explicit user choice.
The cheapest reasoning model is the one you do not call. Route easy tasks to a non-reasoning model, cap budgets on everything else, and reserve high effort for the small fraction of traffic where it actually moves the needle.
What Comes Next for Automatic Effort Selection
Auto-effort selection sounds like a vendor problem. Ship a mode that reads the prompt, estimates complexity, and picks the tier before the main model runs. It should ship in the API. It has not, and the reasons are concrete systems-engineering failures, not missing features.
Naive complexity classification breaks in three ways that no amount of prompt engineering fixes:
- Surface features do not predict difficulty. A short, plainly worded request can be combinatorially hard. "Find the contradiction in these ten contract clauses" looks easy to a classifier reading token count and sentence length. It is not. The inverse is just as common: long, elaborate prompts that decompose into trivial steps.
- Multi-turn conversations shift difficulty mid-stream. The opening turn may be simple, but the third message introduces a constraint that makes the whole thread hard. An effort tier chosen from the first message is stale by the third.
- Tool-call state changes the problem after the first step. A model starts at
loweffort, calls an API, and the returned data reveals the task is far more complex than the prompt suggested. The effort decision was locked in before that state existed.
The architecture that would work in practice is heavier than a prompt classifier. It needs a lightweight router that reads prompt embeddings alongside conversation history and accumulated tool-call state, predicts a token budget, and then falls back to an explicit ceiling when its confidence is low. That router itself costs inference. It also needs to beat a static routing table often enough to justify the overhead, which is a higher bar than it sounds. The task-based routing patterns covered earlier in this article are the simpler version of that architecture, and they already capture most of the value.
Vendors have already tried and retreated. OpenAI's reasoning_effort options for the GPT-5 family shifted between releases, with automatic effort modes restricted after launch, a signal that even the model builder has not cracked reliable auto-selection.
Until auto-selection earns its keep, the fallback is the same principle the routing table above is built on: measure the reasoning ratio on real traffic, route by task type, and cap the budget explicitly. The thinking budget is a resource like memory or CPU. You would not let a process allocate unbounded RAM on the hope that it needs it. Treat reasoning tokens the same way.
Stay in the loop.
Get the latest posts and exclusive content delivered to your inbox.
Join 3 readers. No spam. Unsubscribe in one click, anytime.
About the author
Megan Caldwell
AI Engineering Lead
Megan has spent the last eight years building production ML systems, from recommendation engines to today's language model pipelines. She writes about the engineering that holds up under real load: retrieval, evaluation, and the unglamorous parts of shipping AI software.
Related Posts
Shipping LLM Browser Agents Without Breaking Production
LLM browser agents look easy in demos. Shipping one means defaulting to APIs, containing prompt injection, and budgeting for unpredictable per-step costs.
Run AI Models Locally on Mac With MLX and Nativ
Run AI models locally on Mac with MLX and Nativ. A trade-off framework for when on-device inference beats APIs on cost, privacy, and latency.
Fine-Tuning vs RAG vs Prompt Engineering Decision Framework
Fine-tuning vs RAG vs prompt engineering: run this eval-gated framework before training a custom model and inheriting its hidden maintenance tax.


