TL;DR One level per model. Run
/efforton each model you use and confirm with Enter: it lands inmodelSettings.<model>.effortLevel, and that entry beats the globaleffortLevelin the same file.skeeps it to this session, and/effort autoclears the active model's.
If you use more than one model, you have been working two dials. First /model, then /effort, because the reasoning level you want on the model that investigates for an hour is not the one you want on the model renaming three variables. Since v2.1.251 the second dial travels with the first: Claude Code saves the level per model, so you set it once on each one and switching models brings the right level with it.
Same settings file, two models, two levels:
$ claude --model sonnet --settings '{"effortLevel":"high","modelSettings":{
"claude-sonnet-5":{"effortLevel":"low"},
"claude-opus-5":{"effortLevel":"xhigh"}}}' -p "/whicheffort"
EFFORT=low
$ claude --model opus (same --settings)
EFFORT=xhigh
I never touched /effort and never edited the file between those two lines. I switched models. (/whicheffort is the six-line skill from the precedence tip: still the only way to read the real level from a script.)
Where the level is stored
Open your user settings and look at the two keys that decide this:
$ jq '{effortLevel, modelSettings}' ~/.claude/settings.json
{
"effortLevel": "high",
"modelSettings": {
"claude-opus-5": { "effortLevel": "high" },
"claude-fable-5": { "effortLevel": "high" },
"claude-fable-5-1": { "effortLevel": "high" }
}
}
I wrote the effortLevel at the top months ago. The three entries below it wrote themselves: /effort added one every time I confirmed a level with Enter while sitting on a different model. And since all three say what the global key already said, I have spent months on a single reasoning level across three models I use for jobs that have nothing in common. Writing this tip is what made me open the file.
Two details worth reading closely:
- The model's entry beats the global key inside the same file. That is what the first line of the test above proves:
effortLevel: "high"and stillEFFORT=low, becauseclaude-sonnet-5saidlow. - It is saved under the canonical name (
claude-opus-5) and still applies when you launch with the alias: that test ran as--model sonnetagainst aclaude-sonnet-5entry.
And one thing that does not change: another model's entry leaves you alone. With claude-opus-5 at xhigh while you run Sonnet, you get whatever Sonnet says.
How to leave it set
1. See where you are right now
/effort with no argument reports the level for the model you are on. With something saved, Current effort level: high. With nothing saved, Effort level: auto (currently high), which is the model's own default.
2. Save that model's level
/effort medium
Claude Code answers Set effort level to medium (saved as your default for new sessions) and writes the entry. The /effort slider does the same on Enter, and so does the effort slider inside /model. Want it only for this session? Press s in the slider: the answer changes to (this session only) and nothing is written. It is the same Enter / s split /model uses for the model itself.
One exception: on Fable 5, Opus 4.8 and Opus 4.7, the model holds its own default until you confirm a level by hand. Enter (or typing /effort <level>) releases that hold; launching with --effort does not. Opus 5 and Fable 5.1 have no hold.
3. Do it again on the next model
/model to switch, /effort <level> to pin it there. Which model deserves which is the Sonnet 5, Opus 5 and Fable conversation: the model that delegates and verifies takes a low level far better than the one that investigates on its own.
4. If you change your mind
/effort auto
That clears the saved level for the active model and hands it back to its default. Other models' entries and the global key stay put.
Reference
| How you set it | Scope | What it leaves behind |
|---|---|---|
/effort <level> or Enter in the slider |
That model, new sessions included | modelSettings.<model>.effortLevel |
s in the /effort or /model slider |
This session only | Nothing |
/effort max |
This session only | Nothing, max is not accepted in settings |
/effort auto |
Back to that model's default | Removes that entry |
effortLevel by hand in settings |
Models without an entry of their own | Whatever you type |
--effort at launch |
That session only | Nothing |
CLAUDE_CODE_EFFORT_LEVEL |
The session, and it beats everything above | Nothing |
The per-model cap: maxEffortLevel
The model's entry takes one more field: maxEffortLevel. It trims anything you ask for above it, the launch flag included.
$ claude --model sonnet --effort xhigh \
--settings '{"modelSettings":{"claude-sonnet-5":{"maxEffortLevel":"low"}}}' \
-p "/whicheffort"
Effort 'xhigh' exceeds the cap for claude-sonnet-5 set by your settings or organization; using 'low'
EFFORT=low
That warning is the exception: effort in settings fails silently when you type a level that does not exist, and this cap is the one piece that tells you it trimmed what you asked for.
The model your subagents run on
Your subagents do not inherit your level by default. They run on the model Claude passes when it starts them, or the one in their definition, and only when neither applies do they inherit your conversation's. CLAUDE_CODE_SUBAGENT_MODEL sits behind both of those: since v2.1.251 it is a default value, not an override. To make it win outright, pair it up:
{
"env": {
"CLAUDE_CODE_SUBAGENT_MODEL": "haiku",
"CLAUDE_CODE_SUBAGENT_MODEL_FORCE": "1"
}
}
Where you check that it took is the /tasks panel. Each subagent's row carries the model it runs on, and adds the effort level when its definition, or the skill it forked from, sets effort in frontmatter. The row as the panel prints it:
craft:review › Adversarial review of cache-marker patch
9m 21s · 118.4k tokens · 45 tools · Opus 5 (1M context)
One old reason to leave the dial alone mid-task is still around: changing effort used to break the cache, and the next request reread the whole conversation. On Fable 5.1 with an API key or a Claude subscription it no longer does, as of v2.1.260: Claude Code applies the new level without asking. Every other model still asks before breaking it, which is exactly why the level is better set in advance.
Official docs: Model configuration: adjust effort level ·
modelSettings· Sub-agents: choose a model
Requirements
- Checked on Claude Code v2.1.269. What I ran are the
--settingsprobes in this tip, the cap warning included. The/effort,sand/effort autoreplies are the exact strings from the v2.1.269 binary rather than a captured interactive session, and the/tasksrow comes from the panel itself. modelSettingsneeds v2.1.251, the slider'sskey needs v2.1.257, a per-modelmaxEffortLevelneeds v2.1.267, and the model on the/tasksrow needs v2.1.242.- Saving a level with Enter is an interactive session on your own machine: under
-p,/effortapplies to that session only and writes nothing.