
One afternoon, one Opus 4.1 session running an OpenClaw agent loop on a refactor task, and the bill came to $47.82. That's according to the author's own account. Analysts looking at comparable workloads figure Haiku 4.5 would've knocked out the same task for a fraction of the price.
That single session is what this post is really about. Can you actually trust an auto router to pick the right model tier, or does blind trust just push the cost somewhere you won't notice until the invoice lands? The gap between $47.82 and the cheaper path is the whole case for multi model routing, and it's also the whole case for why auto routing isn't free. OpenClaw's tiered setup, and the Haimaker auto router built on top of it, run on a simple idea: cheap model for cheap work, expensive model for the stuff that needs real reasoning depth. The catch is that the router has to guess which tier a task belongs to before the task runs. That guess is where things get interesting, and not in a good way.
What Changes With A Three Tier Model Setup
Three Tier Model Routing Flow
How OpenClaw Assigns a Task to a Model Tier
Router reads prompt text, token count, keyword density
Compared against escalation_threshold
Task runs on guessed tier, Haiku, Sonnet, or Opus
Task escalates to a higher, costlier tier
Always defaults to fallback_tier regardless of task
Source: Source: Article, OpenClaw config description
The pitch is simple enough. Configure three model tiers, point OpenClaw at all three through one config, then either drive selection yourself with slash commands or hand the wheel to the router. I ran both for several weeks on a mixed workload: Python refactors, MCP server debugging, doc generation, and a handful of genuinely hard architecture calls. Manual control keeps you honest about what a task actually costs. Auto routing takes that friction away, which is the whole appeal, but it also takes away your ability to catch the router when it screws up.
- Tier 1 runs Haiku 4.5 for boilerplate, formatting, docstrings, the stuff nobody wants to think hard about
- Tier 2 runs Sonnet 4.5 for standard refactors and MCP server config debugging
- Tier 3 runs Opus 4.1 for multi file architecture changes and the bug reports that don't make sense yet
- /model gives you a manual override, no session restart needed
- /agent swaps the acting persona and permissions, not just the model weights underneath
The config itself is short. Here's roughly what a three tier setup looks like once you strip the comments out.
models:
tier1:
provider: anthropic
model: claude-haiku-4-5
max_tokens: 4096
tier2:
provider: anthropic
model: claude-sonnet-4-5
max_tokens: 8192
tier3:
provider: anthropic
model: claude-opus-4-1
max_tokens: 16384
router:
mode: auto
fallback_tier: tier2
escalation_threshold: (illustrative value; check your own config for the actual default)
Nobody reads the escalation_threshold line carefully, and that's the mistake. It's a confidence score the router assigns to its own tier guess, and if that guess falls below the threshold, it escalates rather than risk a wrong answer on a cheap model. Set it too low and everything defaults to Opus 4.1. Set it too high and Haiku 4.5 will happily try to reason through a race condition in async code, confidently, and wrong. Where does that threshold number actually come from? Who validated it against a real workload instead of a benchmark suite? Nobody I could find. Next up: what happens when that threshold gets it wrong on tasks that look simple but aren't.
Where OpenClaw's Router Breaks On Real Tasks
Three Tier Model Setup: Specs and Intended Use
OpenClaw Model Tiers at a Glance
| Tier | Model | Max Tokens | Intended Use |
|---|---|---|---|
| Tier 1 | Haiku 4.5 | 4,096 | Boilerplate, formatting, docstrings |
| Tier 2 | Sonnet 4.5 | 8,192 | Standard refactors, MCP config debugging |
| Tier 3 | Opus 4.1 | 16,384 | Multi file architecture, unclear bug reports |
| Fallback | Tier 2 (Sonnet 4.5) | 8,192 | Default for every new session |
Source: Source: Article, illustrative OpenClaw config
The router isn't making a semantic judgment about what a task needs. It's pattern matching against token count, keyword density, and prior escalation history for similar prompts. Fine, until a task description undersells its own complexity, which happens constantly with real bug reports.
- A short bug report like "fix the flaky test in test_auth.py" got routed to Tier 1 more than once before escalating, apparently because prompt length dominated the signal
- Tasks mentioning an MCP server config landed on Tier 2 even when the fix needed cross referencing three files, because the router underweights file count
- Late in long sessions the router's confidence scoring degraded, and Tier 3 style questions kept getting sent to Tier 2
- New sessions default to fallback_tier every single time, so the first prompt of the day is never optimally routed no matter what it actually asks for
- Escalation events produce no log line by default. The cost stays invisible until the invoice shows up.
That last one is the real problem. I assumed, wrongly, that escalation events would show up somewhere in the session output. They don't, not unless you turn on verbose routing logs explicitly. Here's the debug flag that actually surfaces it, buried a few pages into the CLI reference instead of the setup docs where it belongs.
openclaw run --router-verbose --log-level=debug task.md
stderr output includes lines like:
The Cost of One Misrouted Session
One Refactor Task, Two Possible Bills
Actual Bill (Opus 4.1)
$47.82
Estimated Cost (Haiku 4.5)
Fraction of $47.82
The gap between these two numbers is the entire case for multi tier routing, and the entire risk of trusting auto routing without checking its guesses.
Source: Source: Author's account of a single Opus 4.1 session
[router] confidence=(example value) threshold=(example value) -> escalating tier2 to tier3
[router] reason: ambiguous_scope, file_count=4
Flip that flag on and the router stops feeling mysterious. It starts feeling like a decision log you can actually audit. Should this be on by default for anyone running billable API keys through this thing? Yes, obviously, and the fact that it isn't feels like a defaults choice someone should push back on. Once you can see the failure modes, the next question is how manual control stacks up against them directly.
Manual Switching Compared To The Router's Guesses
Manual control with /model and /agent isn't smarter than the router. It's just honest. You know exactly what you're paying for because you made the call yourself. The tradeoff is attention: you have to think about task complexity before every single prompt, which gets exhausting fast on a busy day, and it's easy to get wrong when you're tired or juggling five things at once.
- /model tier3 switches instantly and applies to the next turn only, unless you pin it
- /model tier1 --pin locks the session to that tier until you explicitly unpin it
- /agent reviewer swaps to a config with a different system prompt and different tool permissions
- Manual mode shows running token cost in the prompt bar by default
- Over about a week of informal tracking, the switching overhead settled into something closer to a minor pause than a real interruption
I ran the same batch of roughly forty real tasks twice, once manual, once auto. Manual came out noticeably cheaper overall. That's not a benchmark claim, it's a pattern from one workload over one week, and the ratio will shift depending on how much of the work is genuinely ambiguous versus obviously simple or obviously hard. Auto routing wins big on workloads that are mostly boilerplate with occasional hard spikes, because that's exactly the pattern its confidence scoring was tuned for.
Manual wins when you've got a lot of short, deceptively simple prompts, the flaky test example above being the clean case. If most of your job is terse bug triage like that, does the router's length based signal actually help more often than it hurts? Worth asking, because the answer points straight at how to configure the router so it stops bleeding money quietly.
Configuring The Router Without Losing Money
Running the auto router in anything resembling production means treating the threshold and logging config as load bearing, not cosmetic. The defaults are tuned for a generic workload, not yours, and the failure mode isn't an error you'd notice. It's invisible cost.
- Turn on router_verbose from day one, not after the first invoice that makes your stomach drop
- Set escalation_threshold lower than the default if your workload skews toward short, deceptively complex prompts
- Pin tier1 explicitly for known boilerplate work instead of trusting the router's guess every time
- Check fallback_tier cost, since cold starts and long session drift both land there by default
- Re run the same task set weekly. The router's pattern matching shifts as usage history piles up, and last week's tuning doesn't necessarily hold.
Here's a minimal wrapper that logs every routing decision to a file you can review at the end of the week, instead of trusting stderr scrollback you'll never scroll back through.
import subprocess
import json
from datetime import datetime
def run_with_routing_log(task_path: str, log_path: str = "router_log.jsonl"):
result = subprocess.run(
["openclaw", "run", "--router-verbose", "--log-level=debug", task_path],
capture_output=True, text=True
)
entry = {
"timestamp": datetime.utcnow().isoformat(),
"task": task_path,
"stderr": result.stderr,
"returncode": result.returncode,
}
with open(log_path, "a") as f:
f.write(json.dumps(entry) + "\n")
return result
if __name__ == "__main__":
run_with_routing_log("task.md")
None of this is hard engineering. It's a thirty minute setup, and it's the difference between trusting a router blindly and actually auditing it, a difference that only shows up when the invoice does.
So, back to that $47.82 afternoon: the multi tier idea holds up, and the savings are real when the routing guesses land right. That session got expensive specifically because nothing was logging the escalation that caused it. Three weeks in, a router tuned on aggregate patterns across a bunch of different accounts still can't outperform a developer who knows their own workload's rhythm, terse bug reports and all, at least not without verbose logging and threshold tuning switched on from day one. Until routers get audited by default instead of by accident, bet on the developer who checks the router's work over the one who assumes the router's already checking itself.