routing-savings benchmark · measured

The cost of a model you didn't need.

deadeye routes each subagent task to the cheapest model tier that can still do it. We measured what that's worth — in real billed dollars, graded by a test the model never saw.

3–10×
what opus billed over haiku for identical, correct output (median ~5.7×)
5 / 6
well-scoped tasks passed on the cheapest tier — downshift nearly free
48%
model-cost cut the router actually achieved — 74% of the oracle ceiling
100%
measured, hidden-test graded — no estimated numbers

18 runs · 6 tasks × 3 tiers (haiku · sonnet · opus) · real total_cost_usd · router arm re-measured over 5 trials/task

The proof — over-provisioning has a price

Same task, done correctly: how many × more opus billed than haiku

semver
10.0×
wordwrap
6.6×
csv
4.7×
clamp
3.3×

Bar = opus ÷ haiku billed cost, for output both tiers got correct. Per-task and mix-independent — the robust claim. (sonnet ran 2.0–6.6× haiku.) Only tasks both tiers passed appear here; counter is absent because opus failed it this sweep — see below.

And the cheaper tier actually did the work

TaskBandhaikusonnetopusCheapest that passed
clampmech$0.035PASS$0.070PASS$0.118PASShaiku
wordwrapstd$0.042PASS$0.132PASS$0.279PASShaiku
csvstd$0.067PASS$0.142PASS$0.314PASShaiku
semverhard$0.044PASS$0.166PASS$0.441PASShaiku
expr-evalhard$0.058FAIL$0.253FAIL$0.392FAILnone
counterhard$0.038PASS$0.251PASS$0.251FAILhaiku

5 of 6 well-scoped tasks passed on haiku — including SemVer precedence and a concurrent counter under -race. Note counter: haiku and sonnet passed and opus failed — a reminder that a single trial is one sample, and that paying more is not the same as being right. The task no tier cleared (expr-eval) is the route-up case — more on that below.

How we measured it

One run — repeated 18 times

A "saving" is fake if the cheap model fails — you re-run on opus and pay twice. So every run measures both cost and quality, and a saving counts only when the cheaper tier actually cleared the task.

01 · ISOLATE

Clean tree

git archive HEAD into a fresh temp dir — runs can't contaminate each other.

02 · RUN

Real session

claude -p --model <tier> writes the actual code. DEADEYE=off — raw model cost.

03 · GRADE

Blind test

A hidden go test the model never saw runs against its output. Pass or fail.

04 · MEASURE

Real dollars

Billed total_cost_usd + tokens from the run's JSON. Nothing estimated.

The hidden test is the trick: grade against a spec the model couldn't see, and a pass means it understood the task, not that it gamed the test. Each hidden test was first validated against a known-correct reference impl — so a failure is the model's, not the test's.

The task set — three difficulty bands, on purpose

mechanical
  • clamp(v, lo, hi)
Trivial. Should pass on every tier — so opus here is pure waste.
standard
  • word-wrap (runes)
  • CSV parser
Edge cases — unicode width, empty fields, escaped quotes — where a weak tier might slip.
hard
  • SemVer compare
  • expression eval
  • concurrent counter
Reasoning-heavy. Where opus should actually be needed — the route-up case.

If cheap tiers passed everything, the honest verdict would be "just use haiku" — an anti-routing result. We needed one task where the cheap tier fails and opus is needed. That's the expression evaluator.

The frontier — why one task earns opus

expr-eval sits past the capability edge — on every tier

The recursive expression evaluator (operator precedence, unary minus, error handling) failed on all three tiers, in both full sweeps. An earlier single-trial note here claimed opus passed it on a manual re-run; two sweeps have since contradicted that, so the claim is retired rather than repeated.

Before blaming the models, we checked the grader: the hidden test was re-validated against an independently written correct implementation and passes. So these are genuine one-shot model failures, not a broken fixture.

It earns no saving in either arm — nothing to downshift to. The honest read is narrower than the original framing: this task marks where one-shot generation runs out on every tier we tested, not where opus starts winning.

The number that actually matters

The oracle is a ceiling. What does the router hit?

Everything above measures tiers — what each costs, what each can do. From that you can compute the oracle: perfect hindsight, always picking the cheapest tier that turned out to pass. On this set that's a 66% cut vs all-opus.

But nobody ships with hindsight. The question that decides whether routing is worth anything is what deadeye's own router picks, cold, from the task description alone — so we measured that too, and charged every wrong-cheap route the cost of the re-run on the next tier up. A bad guess loses money here; it doesn't quietly score as a saving.

5 / 6
tasks where the router picked the same tier the oracle would
48%
cost cut actually realized, re-runs charged — vs the 66% ceiling
74%
of the available ceiling captured by the real router
5 / 5
trials picking the same tier on every task — no flapping

The gap between 48% and 66% is the router's remaining error, and it's one task: expr-eval, which nothing passes, so any route pays the full ladder.

What the first measurement found · v0.54.0

The first time we ran this arm it scored 29%, agreed with the oracle on 2 of 6 tasks, and picked different tiers for the same prompt across repeat trials on four of them. The cause wasn't model noise — it was our own classifier prompt. It called tier 1 "most real tasks" (a standing thumb on the scale toward the middle tier) and defined the cheap tier by edit size, leaving nowhere to put "write one self-contained function from a complete spec." So it graded difficulty by how advanced the topic sounded: SemVer precedence and a race-safe concurrent counter both got sent up, while haiku passed both against the hidden test. Rewritten around scope and specification instead of subject matter — with the tie-break deliberately scoped to the cheap end, since guessing low on security or architecture is the expensive direction to be wrong in — it went to 48%, 5-of-6, and stable across every trial. A judge-probe.sh suite now guards the obvious way to fake that number: a classifier collapsed to "always cheapest" would ace this benchmark, so seven probes (cross-file refactor, under-specified integration, subtle debugging, security, architecture) fail the build if anything routes down that shouldn't.

The honest caveats — written into the benchmark

  • Both percentages depend on the task mix. The 66% oracle ceiling and the 48% the router realized are specific to these six tasks. Lead with the 3–10× ratio, which doesn't move with the mix.
  • Single trial per (task, tier) is noisy. This sweep is the proof: counter passed on haiku and sonnet but failed on opus, and it passed on all three last time. Multi-trial pass-rates are the next rigor step.
  • The router's stability is one sample, not a guarantee. Five trials per task all agreed after the recalibration — but claude -p exposes no temperature or seed control, so this has to be re-measured after any change to the classifier, never assumed.
  • The 48% is measured on the set the classifier was corrected against. The prompt was rewritten after this benchmark showed haiku passing SemVer and the concurrent counter — then scored on those same six tasks. That's tuning and grading on one set, so read 48% as optimistic. What survives the objection is narrower and still worth something: the direction of the fix was principled rather than fitted (judge scope and specification, not subject matter), and the seven-probe discrimination suite is held out from the benchmark — it fails if the classifier buys a better score by routing everything down. A fresh, unseen task set is the honest next test.
  • Small self-contained tasks under-count the tier gap. Large, context-heavy real work is where cheaper tiers slip more — so this is a floor on the value of routing up, not a ceiling.
  • Cache-heavy system-prompt cost is in every run and similar across tiers, so it dilutes the headline %. The model-priced delta is the real lever.

Correct output costs about 6× more on opus. deadeye routes it down.

← back to deadeye