BYOKchat Blog

Reasoning Effort Explained: Low, Medium, High, and Beyond

Understand what AI reasoning-effort controls do, how they differ across OpenAI, Gemini, and Claude, and how client apps should expose reasoning settings safely.

· 9 min read

On this page
  1. Reasoning effort is not answer length
  2. Reasoning effort is not temperature
  3. Reasoning effort is not a guaranteed token count
  4. Current providers expose different control surfaces
  5. OpenAI: reasoning effort is model capability
  6. Gemini: thinking level depends on model generation
  7. Claude: adaptive thinking changes the old budget model
  8. Do not normalize by pretending all values are equivalent
  9. A portable “intent” layer can still be useful
  10. Preserve native controls for advanced users
  11. Defaults matter more than they look
  12. “None” and “minimal” are not the same concept
  13. More effort can increase latency
  14. More effort can increase token usage and cost
  15. More effort does not guarantee a better answer
  16. Excessive reasoning can be actively undesirable
  17. Reasoning effort can affect tool behavior
  18. Tool-loop cost can amplify effort changes
  19. Reasoning and output budget interact
  20. Reasoning controls should be validated before sending
  21. Silent downgrade is dangerous
  22. Store reasoning settings per model or per chat?
  23. Global default
  24. Per-provider/model preference
  25. Per-chat setting
  26. Per-request override
  27. Preserve “provider default” as an option
  28. Model switching should revalidate effort
  29. Provider switching makes raw enum persistence brittle
  30. Reasoning effort should be visible in analytics
  31. Evaluate effort on a workload-specific test set
  32. Keep model version fixed when comparing effort
  33. Do not hide reasoning-model incompatibilities behind OpenAI-compatible APIs
  34. UI labels should explain the tradeoff
  35. Reasoning visibility is separate from reasoning effort
  36. A capability-oriented model
  37. Common mistakes
  38. Treating medium as standardized across providers
  39. Treating high effort as long output
  40. Assuming unsupported levels will be ignored safely
  41. Hiding model changes
  42. Storing one provider-native value as universal chat state
  43. Using maximum effort by default for everything
  44. Reasoning-control checklist
  45. Where BYOKchat fits
  46. Further reading

A reasoning-effort control tells a model how much reasoning work to spend on a request, within the behavior supported by that model/API.

It is not a universal unit.

This is the most important rule:

medium on one model is not a standardized amount of computation that can be compared directly with medium on another provider.

Reasoning controls are model-specific knobs that influence a tradeoff among quality, latency, token usage, and sometimes tool behavior.

Reasoning effort is not answer length

If you set a model to high reasoning effort, you are not asking for a longer visible answer.

These are separate concerns:

reasoning effort → how much internal reasoning/computation the model is encouraged to use
output limit     → how many generated tokens the API permits
style instruction → how long/detailed the visible answer should be

A high-effort model can still return a one-sentence answer.

A low-effort model can still generate a long answer if the task and output budget call for one.

Reasoning effort is not temperature

Sampling controls affect how generation choices are selected.

Reasoning effort affects how much reasoning the model is configured to perform.

They solve different problems.

Do not map a UI control like:

More accurate ↔ More creative

to reasoning effort. Creativity and reasoning depth are not opposite ends of one axis.

Reasoning effort is not a guaranteed token count

An effort level such as:

low
medium
high

usually does not mean:

low = exactly 1,000 thinking tokens
medium = exactly 4,000
high = exactly 8,000

unless a provider explicitly documents a fixed mapping for a particular API/model.

Modern reasoning systems often use dynamic reasoning, so two high-effort requests can consume very different amounts depending on task complexity.

Current providers expose different control surfaces

As of September 2026, the major APIs do not use one shared reasoning-control contract.

Examples:

  • OpenAI GPT-5.6 models expose reasoning.effort, with supported values depending on the model; current GPT-5.6 guidance documents none, low, medium, high, xhigh, and max for the flagship family.
  • Current Gemini thinking models use model-dependent thinking_level values such as minimal, low, medium, and high; older Gemini 2.5-style APIs also used numeric thinking budgets.
  • Current Claude models can expose adaptive thinking plus an effort control; exact support differs by model generation, and older manual budget_tokens behavior is not the right abstraction for every newer Claude model.

These interfaces evolve. A client should query/maintain model capability metadata rather than assuming a fixed four-level enum forever.

OpenAI: reasoning effort is model capability

Current OpenAI guidance for GPT-5.6 recommends setting reasoning.effort intentionally.

Conceptually:

{
  "reasoning": {
    "effort": "medium"
  }
}

But not every historical or future model necessarily supports the same values.

A client should know:

model supports reasoning?
supported effort values?
default effort?
can reasoning be disabled?

Do not show max merely because another GPT model supports it.

Gemini: thinking level depends on model generation

Current Gemini APIs distinguish newer thinking-level controls from older numeric thinking-budget controls.

For newer Gemini thinking models, the application may configure values such as:

minimal
low
medium
high

with the exact supported set depending on the model.

Some models do not support fully disabling thinking.

That means a generic UI toggle:

Reasoning: On / Off

can be incorrect for models where the minimum is “minimal thinking,” not zero thinking.

Claude: adaptive thinking changes the old budget model

Current Claude guidance increasingly favors adaptive thinking with an effort setting on newer models rather than treating a fixed budget_tokens value as the universal interface.

That matters for app architecture.

If your canonical model is:

thinkingBudgetTokens: Int

then newer models that support qualitative effort but not the same manual budget semantics fit poorly.

A capability-oriented abstraction is more durable.

Do not normalize by pretending all values are equivalent

This looks convenient:

enum ReasoningEffort {
    case low
    case medium
    case high
}

but it can hide provider differences.

A better model can distinguish semantic intent from native support:

struct ReasoningCapability {
    let mode: ReasoningMode
    let supportedLevels: [ReasoningLevel]
    let nativeOptions: ProviderReasoningOptions
}

Then the UI can expose only valid choices.

A portable “intent” layer can still be useful

You may want a high-level product preference:

fast
balanced
deep

That can map to native provider controls.

But this mapping is your product policy, not a fact about equivalence.

For example:

Fast     → OpenAI low / Gemini low / Claude low
Balanced → provider/model default or medium
Deep     → high where supported

This can be a good UX if the app clearly treats it as an abstraction and maintains mappings per model.

Preserve native controls for advanced users

A BYOK client serving technical users may benefit from two levels:

simple mode → Fast / Balanced / Deep
developer mode → native supported effort values

This avoids overwhelming normal users while still allowing exact control where useful.

Defaults matter more than they look

If a client omits the reasoning parameter, the model/provider chooses its default.

Defaults can differ by model and can change when an alias points to a newer model revision.

Therefore:

unset

should not always be serialized as:

medium

Those are different choices.

Model unset as a real state when the provider has a meaningful native default.

“None” and “minimal” are not the same concept

Some models support a true no-reasoning mode.

Others support only a minimum reasoning level.

Do not collapse:

none
minimal
low

into one false value.

A model can perform minimal thinking while still producing reasoning-token usage.

More effort can increase latency

Reasoning takes time.

A simplified request timeline might be:

network setup
→ provider queue
→ reasoning
→ visible generation
→ completion

Higher effort can increase the reasoning portion before or during visible output.

That can affect:

  • time to first visible token;
  • total duration;
  • battery/network UX on mobile;
  • tool-call latency;
  • user perception.

Measure it rather than promising fixed latency ratios.

More effort can increase token usage and cost

Reasoning models can consume internal generated tokens that are billed or counted even when they are not fully visible.

Therefore a high-effort request may cost more than a low-effort request with the same final answer length.

Use provider-reported usage fields where available.

See How to Estimate AI Request Cost Before Sending.

More effort does not guarantee a better answer

A harder reasoning setting can help on tasks such as:

  • complex code debugging;
  • multi-step planning;
  • mathematics;
  • constraint-heavy design;
  • synthesis across several sources;
  • multi-tool workflows.

It may add little value for:

  • simple rewriting;
  • deterministic formatting;
  • obvious extraction;
  • short classification;
  • direct factual lookup with trusted evidence.

The correct setting depends on workload.

Excessive reasoning can be actively undesirable

For some workloads you want:

low latency
low cost
predictable short output

Forcing maximum reasoning can increase delay without meaningfully improving correctness.

A production app should optimize for the task, not for the highest available setting.

Reasoning effort can affect tool behavior

A model that reasons more may:

  • plan more before calling a tool;
  • issue different tool queries;
  • use more tool rounds;
  • verify intermediate results more often;
  • decide no tool is needed.

This means effort can change not only token usage but the entire agentic execution path.

Test tool-enabled workloads separately from plain chat.

Tool-loop cost can amplify effort changes

Suppose high effort causes two extra model/tool rounds.

The total cost can grow through:

more reasoning tokens
+
more model requests
+
larger accumulated context
+
more tool execution

Do not estimate agent cost from reasoning tokens alone.

Reasoning and output budget interact

If reasoning tokens share a generation budget with visible output for a provider/model, high reasoning can reduce the remaining answer headroom.

A user asking for a long report may need both:

sufficient reasoning effort
sufficient generation/output limit

Setting high effort without enough output capacity can yield a well-reasoned but truncated answer.

See Context Window vs Output Limit vs Reasoning Tokens.

Reasoning controls should be validated before sending

Do not let the provider discover invalid combinations for you on every request.

A client can validate:

selected model supports reasoning
selected effort is supported
thinking-off is allowed
native parameters are mutually compatible

Then show a clear UI error or adjust only according to an explicit product policy.

Silent downgrade is dangerous

Suppose the user selects high but the target model supports only low and medium.

Bad behavior:

silently send medium

Better options:

show unsupported setting
reset with explicit notice
or preserve model-specific settings per model

The user should know when the requested behavior changed.

Store reasoning settings per model or per chat?

There are several valid designs.

Global default

Good for simple apps, but one value may not fit every model.

Per-provider/model preference

Useful when model capabilities differ substantially.

Per-chat setting

Useful when one conversation is latency-sensitive and another is deep technical work.

Per-request override

Useful for one unusually hard turn.

A layered policy can combine them:

per-request override
→ per-chat setting
→ model preference
→ provider default

Resolve this deterministically before request construction.

Preserve “provider default” as an option

Advanced clients should often allow:

Reasoning: Provider Default

That means omit/choose the provider’s default semantics rather than forcing the app’s preferred level.

It also reduces maintenance when providers tune defaults over time.

Model switching should revalidate effort

If a chat changes from Model A to Model B:

A supports: none, low, medium, high, max
B supports: low, medium, high

The previous max setting cannot carry over literally.

The client should:

  1. inspect B’s capabilities;
  2. preserve a portable intent if your product has one;
  3. choose/ask for a valid B setting;
  4. avoid silently serializing invalid native values.

See Capability Detection in Multi-Model AI Apps.

Provider switching makes raw enum persistence brittle

If your database stores:

reasoningEffort = "xhigh"

as a universal chat field, a non-OpenAI provider may not understand it.

Better:

portable reasoning preference
+
provider/model-native override metadata

This keeps portability without throwing away advanced controls.

Reasoning effort should be visible in analytics

Useful content-free metrics:

provider/model
reasoning level
input tokens
output tokens
reasoning tokens when reported
TTFT
total duration
tool rounds
success/failure

Then you can answer:

Does high effort improve this task enough to justify the latency/cost?

without logging prompts.

Evaluate effort on a workload-specific test set

Do not benchmark reasoning effort on random trivia if your app is a coding client.

Use representative tasks:

multi-file bug diagnosis
architecture comparison
simple rewrite
structured extraction
multi-tool workflow
long-context synthesis

Compare:

  • correctness;
  • completion rate;
  • latency;
  • token usage;
  • tool behavior;
  • human preference.

Keep model version fixed when comparing effort

If you compare:

Model v1 high
vs
Model v2 medium

and conclude “high is better,” the experiment is confounded.

Keep model/version and prompt fixed when testing effort levels.

Do not hide reasoning-model incompatibilities behind OpenAI-compatible APIs

A third-party OpenAI-compatible server may accept a reasoning_effort field but:

  • ignore it;
  • reject some values;
  • map it differently;
  • expose a non-reasoning model.

Capability detection and error handling matter more than request-schema familiarity.

See OpenAI-Compatible Does Not Mean OpenAI-Identical in the provider phase.

UI labels should explain the tradeoff

A compact UI can say:

Low — faster, less reasoning
Medium — balanced
High — deeper reasoning, potentially slower

Avoid guarantees such as:

High — always more accurate

That is not defensible across tasks.

Reasoning visibility is separate from reasoning effort

A provider may expose reasoning summaries or thinking traces independently of the selected effort.

Do not couple:

show reasoning UI

with:

enable high reasoning

One is a presentation capability. The other is an execution setting.

A capability-oriented model

enum ReasoningLevel: String {
    case none, minimal, low, medium, high, xhigh, max
}

struct ReasoningCapability {
    let supported: Bool
    let levels: [ReasoningLevel]
    let defaultLevel: ReasoningLevel?
    let canDisable: Bool?
    let nativeMode: String
}

The exact type can be richer, but the principle is to let capability data drive UI and validation.

Common mistakes

Treating medium as standardized across providers

It is not.

Treating high effort as long output

Output length is a separate control.

Assuming unsupported levels will be ignored safely

They may cause errors or unexpected fallback.

Hiding model changes

A new model may have a different default or supported set.

Storing one provider-native value as universal chat state

Breaks provider portability.

Using maximum effort by default for everything

Can waste latency and cost.

Reasoning-control checklist

  • Discover/maintain reasoning capability per model.
  • Preserve provider-default as a distinct state.
  • Keep effort separate from output length and sampling.
  • Do not assume equal-named levels are computationally equivalent.
  • Validate settings before sending.
  • Revalidate after model/provider switches.
  • Avoid silent downgrade.
  • Measure latency, usage, and task quality by effort level.
  • Keep native provider options available for advanced use when valuable.
  • Treat provider documentation as the source of truth for current supported levels.

Where BYOKchat fits

A multi-provider BYOK client can expose a clean reasoning control while keeping native differences behind provider/model capability metadata. The chat can store a portable preference, and the selected adapter can map that preference to an exact supported option—or tell the UI that no valid mapping exists.

That is safer than pretending every reasoning API has the same three-position switch.

Further reading

Keep reading