Output tokens are where the gap shows. At the list prices our catalog carries today, GPT-4o is $10.00 per million against GPT-4o-mini's $0.60, about 16×. Claude Opus is $25 against Sonnet's $10, about 2.5×. Gemini 2.5 Pro is $10 against Flash's $2.50, about 4×. Provider list prices move, so check today's before you plan around one of those numbers.
Most teams hard-code the model name anyway. They pick the top of the ladder because it works on every prompt, and nobody wants to debug a quality regression in the week they ship.
Route by budget pressure, not request type
Request type is the wrong unit. A "summarization" call might be 200 tokens or 200,000. A "chat" call might be a one-line FAQ answer or an hour of research dialogue. Rules built on those labels break the first time traffic shifts.
Budget pressure holds up better. While a team is comfortably under its limit, use the good model. Once it crosses, downgrade until the limit resets. The trigger moves with real spend; the policy stays one line.
The rule we recommend
Give each team its own budget. When a team crosses it, that team's later calls run on the cheaper model until the budget resets. Teams that stay under never notice. The team running hot keeps working instead of hitting a wall.
That is the Switch each team or feature to a cheaper model after $X template on the Firewall page. You name the tag, every value of it gets its own pool and its own threshold ($5 by default), and only the value that crosses gets switched. The reset is a sliding inactivity window, so a team that goes quiet starts clean. Project-wide there is Switch to a cheaper model after $X (one shared pool, $500 by default). With no limit at all, Send free users to a cheaper model swaps every call on a plan from the first request. See templates and the recipe end to end.
What a reroute will and won't swap
Swaps are same-provider only: gpt-4o to gpt-4o-mini, Claude Opus to Sonnet, Gemini 2.5 Pro to Flash, one Bedrock model to a smaller Bedrock model. The target has to be a model we hold a price for, or the rule won't save. And a reroute never unpins a model you asked for. If the target resolves to the model already requested, nothing is swapped.
One caveat is worth reading twice. Reroute does not switch the model on LangChain, LangGraph, LlamaIndex, Pydantic AI or the Vercel AI SDK. Those calls run on the model your code named and land in the Audit log as Reroute rejected (Actions). So check the Audit log before you enforce. The Routing tab only lists swaps that actually happened, which makes a rule that never fires look the same as a rule that can't.
The Routing tab counts calls, not dollars. The feed under it names the rule, the user and the swap.
Run it in dry-run first
Two dials decide whether a swap really happens: the rule's mode, and the SDK's firewall mode in your app. Both have to say enforce. New reroute rules start in dry-run, which is where you want them. Leave one running against production traffic for a week, read the "would have rerouted" count, sample those calls, and decide whether the cheaper model is good enough for that slice of your traffic. Then flip it. If the answer is no, narrow the filter and try again. More in dry-run vs enforce.
Where rerouting fits, and what it does not claim to save: cheaper-model routing. Start a routing rule.

