BlogCost & ops8 min read

Try the cheap model first

A cascade sends easy work to a small model and escalates the rest. Whether it saves anything depends on one number most people never measure.

Most workloads are not uniformly hard. A batch of invoices contains clean native PDFs from three known suppliers and a photograph of a crumpled receipt. Running all of them through the same model means paying the price of the hardest document for every document.

A cascade tries a cheap model first and escalates what it cannot handle. The saving is real, and whether it materialises depends on one number that most implementations never measure.

A cascade saves money only if the cheap model succeeds often enough to pay for the escalations. That threshold is computable before you build anything.

The break-even

Let p be the share the cheap model handles correctly. Escalated items cost both models, because you already paid for the failed cheap attempt.

cascade cost = cheap + (1 − p) × expensive
baseline     = expensive

worth it when:   cheap + (1 − p) × expensive  <  expensive
                 cheap  <  p × expensive
                 p  >  cheap / expensive

So the required success rate is just the price ratio. With Haiku 4.5 at $1/$5 and Sonnet 5 at $2/$10, the ratio is 0.5 — the cheap model needs to handle more than half correctly to break even, and the gain grows from there:

Cheap model handlesCost vs Sonnet-onlySaving
50%100%0
70%80%20%
85%65%35%
95%55%45%

The ceiling is 50%, at p = 100% — which is just "use the cheap model". A cascade cannot beat the cheap model's price; it buys you the expensive model's accuracy on the hard tail at a blended rate.

Note what this means for a wider gap. Against Opus 5 at $5/$25, the Haiku ratio is 0.2, so the cheap model only needs 20% success to pay. Cascades get dramatically more attractive as the price gap widens.

Measure p before building anything

This is the step that gets skipped, and it is an afternoon. Run both models over your golden set and compare against labels:

select
  count(*) filter (where cheap_correct)                          as cheap_ok,
  count(*) filter (where not cheap_correct and strong_correct)   as escalation_saves,
  count(*) filter (where not cheap_correct and not strong_correct) as both_fail,
  count(*)                                                        as total
from model_comparison;

If cheap_ok / total is below your price ratio, stop — a cascade costs more than just using the strong model. That is a genuinely common outcome on hard document types, and finding it out in a query beats finding it out from an invoice.

both_fail is worth looking at separately. Those documents are going to review regardless, and a cascade pays two model bills before getting there. If that bucket is large, route it away from models entirely using a cheap upfront signal — image quality score, page count, unknown supplier.

The gate is the hard part

A cascade needs to know when the cheap model failed, without having a label. Getting this wrong ruins the economics in both directions: escalate too eagerly and you pay twice for everything, too rarely and errors ship.

Ranked by how well they actually work:

Validation rules. The strongest signal, and free. If line items do not sum to the total, the extraction is wrong — no confidence estimate required. Deterministic checks like this should always be the first gate.

Schema and refusal. Output that fails the schema, or a field the cheap model marked unreadable, escalates.

Self-reported confidence. Weak, poorly calibrated, and the failure mode is exactly wrong — models are confidently wrong on the cases you most want caught. Use as a tiebreaker, never as the only gate.

Input-side triage. Cheapest of all: route by properties of the document before any model call. Known supplier and clean scan goes cheap; photograph or unknown template goes straight to the strong model. No wasted attempt at all.

async function extract(doc: Document): Promise<Result> {
  // Free triage first — skip the cheap attempt where it is doomed.
  if (doc.quality < 0.5 || !doc.knownSupplier) {
    return await run(STRONG, doc)
  }

  const cheap = await run(CHEAP, doc)

  // Deterministic gates, in order of reliability.
  if (!schemaValid(cheap))        return escalate(doc, "schema")
  if (!arithmeticChecks(cheap))   return escalate(doc, "arithmetic")
  if (cheap.refusals.length > 0)  return escalate(doc, "refusal")

  return cheap
}

Watch the escalation rate

The rate is a live measurement of p, and it moves:

select date_trunc('day', at) as day,
       count(*) filter (where escalated)::float / count(*) as escalation_rate
from extractions
where at > now() - interval '30 days'
group by 1 order by 1 desc;

A rising rate means the cheap model is handling less than it used to — a new supplier template, a change in upload mix, a model version update. Past the break-even ratio the cascade is now costing you money, and it will not announce that.

Alert on it crossing the ratio you computed. That is the number where the whole design stops being worth having.

Where cascades do not fit

Latency-sensitive paths. An escalation is two sequential calls. If a user is waiting, the tail latency roughly doubles for the escalated share.

Small price gaps. The closer the two models are in price, the higher p has to be. Between adjacent tiers it is often not worth the complexity.

When batch is available. For asynchronous work, the Batch API is a flat 50% with no gate to build, no escalation logic, and no accuracy trade. Take the unconditional discount before building a conditional one — and note the two compose, so a cascade running inside a batch gets both.


More in when the model bill triples, which feature tripled the bill, and what an AI feature costs to build. Rates from Anthropic's published pricing, checked 27 August 2026.

Something here

the audit is the cheapest way to find out for certain.