Skip to content
Skip to main content
A brushed teal and stainless steel rotary control knob photographed close up on a brushed metal surface, a metaphor for picking one setting on Claude's five-level effort dial
9 min readBy Carlos Aragon

Claude's Effort Parameter: Which Level to Use

Set output_config.effort to one of five values — low, medium, high, xhigh, max. The API default is high, and passing highdoes exactly nothing that omitting it wouldn't. Set it anyway. And understand this before you touch it: effort is not a thinking budget. It governs every token in the response — tool calls included — which is why it's the biggest cost dial on an agent, not a rounding error.

The Short Answer, By Workload

Classification, extraction, routing, quick lookups? low. These are the requests where marginal quality gains don't justify a single extra second of latency.

Subagents and fan-out workers? low. They're handed a narrow brief and asked for a narrow answer. Paying frontier-depth reasoning per worker is how a fan-out job quietly triples in price — I went through that math in the subagent token cost post.

Your main agent loop on Claude Opus 5? Start at high, then push down and see where quality actually breaks. It usually holds longer than you expect.

Hard coding and long-horizon agentic work on Opus 4.8 or 4.7? Start at xhigh and treat highas the floor. That's the opposite direction from Opus 5, and it's deliberate — more on that below.

A genuinely frontier problem you'd pay anything to get right? max, and then actually measure whether it beat xhigh. Often it doesn't, and on structured output it can overthink its way to a worse answer.

What Effort Actually Controls

Nearly everyone reads “effort” and mentally files it next to the old budget_tokens— a cap on the thinking phase. It isn't. Anthropic's effort documentation says the parameter affects alltokens in the response: text and explanations, tool calls and function arguments, and thinking when it's active. The line worth tattooing on your cost dashboard is this one: “lower effort would mean Claude makes fewer tool calls.”

That's a different kind of knob than a token budget. A budget clamps one phase. Effort changes the shape of the whole turn. Drop to lowand the model consolidates operations into fewer calls, skips the “here's my plan” preamble, and confirms tersely. Push to xhigh and it explains before it acts, calls more tools, and writes you a fuller summary at the end.

For an agent, that's where the money lives. Every tool call is a round trip that resends the conversation and appends a result, so the count of calls drives the bill more than the eloquence of any single response. And the arithmetic is unkind: Claude Opus 5 is $5 per million input tokens and $25 per million output. Output costs 5× input, and effort sits squarely on the output side. Reducing tool-call count is worth more than most of the prompt trimming people do first — the same point I made in the agent cost optimization post.

One nuance from the docs that saves an argument later: effort is a behavioral signal, not a hard cap. At low the model will still think when a problem genuinely demands it. It just thinks less than it would at high on the same problem.

The Five Levels, and Who Each One Is For

LevelWhat you're buyingReach for it when
lowMost efficient. Real token savings, some capability given up.Classification, lookups, high-volume chat, subagents.
mediumBalanced. Moderate savings without falling off a cliff.Agentic work that has to be fast, cheap and decent all at once.
highThe default. Identical to sending nothing.Complex reasoning, hard coding, most agentic tasks.
xhighExtended capability for long-horizon work. Meaningfully more tokens.Half-hour-plus agentic runs, repeated tool calling, deep search.
maxNo constraint on spend at all.The deepest reasoning you can buy, when correctness beats cost.

The ladder isn't uniform across models, and that trips people up. xhigh arrived later than max, so there are models that accept max but reject xhigh— Opus 4.6 and Sonnet 4.6 among them. If you're writing a config layer that maps a string to a model, validate the pair, don't assume five levels everywhere.

And don't pass adaptiveas an effort value. It's a thinking mode, not an effort level. The two parameters sit next to each other and get conflated constantly.

Where to Start, By Model

Here's the part I find genuinely interesting: the recommended starting point reversed between two consecutive Opus releases.

Claude Opus 4.8 and 4.7: start at xhigh for coding and agentic work, use highas the floor for anything intelligence-sensitive, and only step down once your evals prove the lower level holds. The whole posture is “spend, then trim.”

Claude Opus 5: start at high, the default, and use low and medium liberally as your primary control for cost and response time wherever quality holds. Step up to xhighfor demanding coding and agentic work. The posture flipped to “trim, then spend where it's earned” — because the model got good enough at the low end that the old reflex of reaching for xhigh just buys tokens.

Claude Sonnet 5: high is the default and a reasonable home. xhigh for the hardest coding and agentic tasks. medium is roughly Sonnet 4.6 at high, which makes it a clean cost step-down if you're migrating. Worth reading next to the Sonnet 5 vs Opus 4.8 comparison.

Claude Sonnet 4.6: set it explicitly. It defaults to high, and teams moving up from 4.5 — which had no effort parameter at all — get ambushed by the latency. medium is the sane default here.

The operational rule that falls out of all this: an effort setting is not portable across a model change. Run a fresh sweep after you migrate. A value that was correct on 4.8 is very likely wrong on 5, and it'll be wrong in the expensive direction.

Effort Is Not a Verbosity Knob

This one costs people a week. Your users say the answers are too long, you reach for low, and the answers stay long.

On Claude Opus 5, changing effort does not reliably shorten the visible response. Effort moves thinking volume and tool-call behavior. Response length is a separate axis, and the fix is prompting — tell the model to lead with the outcome, keep caveats brief, and skip non-essential context. Anthropic says this outright in the Opus 5 guidance, and it matches what I see: a low-effort turn can still hand back four paragraphs.

Effort still saves you real money on that model. It just saves it in tokens the user never sees, plus the tool calls it declines to make. Those are the right things to be cutting. Just don't expect the UI to change.

The Trap: Effort and Prompt Caching Fight Each Other

“Dynamic effort” sounds obviously correct — cheap level for the easy turn, expensive level for the hard one. And it is correct, for stateless per-request work.

In a multi-turn session it can cost you more than it saves. Effort shapes the rendered prompt, so changing the value between requests doesn't preserve the cached prefix from earlier turns. Cache reads run at roughly a tenth of full input price, so bouncing between medium and xhigh mid-conversation means paying full freight on a history you'd already paid to cache. I wrote up the caching side of this in the prompt caching post, and Anthropic's caching docs cover the prefix-match rule that causes it.

Pick a level when the session starts and hold it. Vary effort across workloads, not within a cached conversation. If you truly need a deeper pass mid-session, fork it into a separate stateless request rather than flipping the dial on the live thread.

The 400 You'll Hit on Opus 5

On Claude Opus 5, thinking: { type: "disabled" } is rejected at xhigh and max. It returns a 400. It's accepted at high and below.

The nasty part is that the check runs per request. A conversation that ran fine for twenty turns at high with thinking off will fail the moment some code path bumps effort to xhigh and leaves the thinking config untouched. Nothing about the earlier successes protects you.

Two related things worth knowing while you're in there. First, thinking is on by default on Opus 5 — omitting the thinking field means the model thinks, which is a reversal from Opus 4.8 where omitting it meant no thinking. Second, max_tokens is a hard cap on thinking plus response text together. A route that ran thinking-off with a snug max_tokens can now truncate mid-answer after nothing more than a model swap. At xhigh or max, start max_tokens around 64k and tune from there.

How I Wire This in Production

I don't decide effort per request. I decide it per workload class, once, and every call site inherits it. That keeps it constant inside any given conversation, which is what caching wants, and it makes the cost model legible when someone asks why the bill moved.

// One place, not scattered across call sites.
const EFFORT = {
  classify:    "low",     // intent + routing, thousands/day
  worker:      "low",     // fan-out subagents, narrow briefs
  chat:        "medium",  // support replies, latency matters
  coordinator: "high",    // the main loop on Opus 5
  deepFix:     "xhigh",   // retry path when the main loop failed
} as const;

await client.messages.create({
  model: "claude-opus-5",
  max_tokens: 64000,            // thinking + text share this cap
  output_config: { effort: EFFORT[workload] },
  messages,
});

The deepFixlane is the piece I'd argue for hardest. Instead of running the whole system at xhighbecause a small fraction of tasks need it, run the fleet cheap and route the failures to one expensive retry. You pay frontier prices only for the requests that actually earned them, and because it's a fresh request rather than a mid-session dial change, it doesn't torch anyone's cache.

Before You Ship

Effort is set explicitly on every route. Not inherited from the default, not left to whoever wrote that handler last quarter.

One level per conversation. If a code path can change it mid-session, that's a cache bug waiting to be discovered on the invoice.

max_tokens is at least 64k anywhere you use xhigh or max. Otherwise you'll ship truncated answers and blame the model.

Response length is handled in the prompt, not the dial.

Every model migration triggers a fresh effort sweep. Add it to the migration checklist next to the model-ID swap, or it won't happen.

Paying Frontier Prices for Classification Work?

Most of the Claude bills I get asked to look at aren't expensive because the prompts are long. They're expensive because one effort level got picked in week one and never revisited, so a routing call and a multi-file refactor cost the same. That's usually a one-afternoon fix with a number attached, and it's a good conversation to have.

Related Posts

AI Models

Claude's 1M Context Window: When to Actually Use It

1M is the default now on Opus and Sonnet, with no beta header and no long-context surcharge — a 900k-token request bills at the same per-token rate as a 9k one. That kills the pricing objection and leaves the two that matter: $4.50 of input per turn adds up fast in a loop, and Anthropic documents context rot in its own docs. Where the full window earns its keep, and where I cap agents at 200K instead.

AI Models

Claude's Compaction API: Long Sessions Without Context Rot

Compaction summarizes a long conversation server-side once it crosses your trigger threshold, and returns the summary as a compaction content block you must pass back every turn. Append only the response text instead of the full response.content and the feature silently does nothing while you pay for it twice. Plus the billing trap: top-level usage excludes the compaction pass, under-reporting a compacting turn by roughly 8x — and why context editing is often the cheaper tool.

AI Models

Claude API 429 Rate Limits: How to Fix Them in Production

A Claude API 429 isn't one limit, it's three — RPM, ITPM and OTPM — enforced per model at the organization level on a token bucket that refills continuously. Honor retry-after before you reach for backoff, add jitter so your workers stop stampeding, log the anthropic-ratelimit headers so you throttle before the error fires, and share one limiter across every worker. Plus the fix almost nobody mentions: cached input tokens don't count toward ITPM, so prompt caching raises your effective ceiling roughly 5x at an 80% hit rate.