Skip to content
Compare· Verified 2026-09-10

What a routing receipt is.

Savings percentages are the currency of this category. Almost none of them will tell you what one request saved.


A percentage is not a measurement

A saving only exists relative to something that did not happen, so the number depends entirely on the baseline — and the baseline is almost never stated.

One baseline survives scrutiny unlabelled: the model the caller asked for. They named it, the token counts are the real ones from the request that just completed, and the answer can come out negative — which is the property that makes it a measurement rather than a marketing claim.

What that looks like on one request

A caller asks for Claude Opus 5, the router scores the prompt and serves Claude Haiku 4.5 instead, and the response comes back with 400 input and 140 output tokens.

400 in + 140 out on Claude Opus 5, the model asked for$0.005500
The same tokens on Claude Haiku 4.5, the model served$0.001100
Saved on this request$0.004400

A worked example, not a measured request: the rates are read at build time from the same registry that bills a real one, and the figure above is arithmetic on them.

It is a fraction of a cent. A month of production traffic is that figure added up rather than asserted, and every term in the sum is one you can check.

And it comes back on the response that caused it:

< HTTP/1.1 200 OK< x-lobstack-request-id:       req_8f3a1c92e0b74d16< x-lobstack-model:            claude-haiku-4-5< x-lobstack-tier:             small< x-lobstack-complexity:       25< x-lobstack-routed:           true< x-lobstack-cost-usd:         0.001100< x-lobstack-savings-usd:      0.004400< x-lobstack-baseline-model:   claude-opus-5< x-lobstack-baseline-reason:  named< x-lobstack-baseline-usd:     0.005500< x-lobstack-priced:           true< x-lobstack-metered:          true

The three baseline headers travel with the figure and never without it. x-lobstack-baseline-reason reads named here, which is the like-for-like case above.

Nothing to query afterwards and nothing to correlate by request id: it arrived in the same place as the answer.

Who actually ships what

This argument used to say no vendor exposes what a request would have cost on the model it did not choose. That was wrong within days.

LiteLLM computes the counterfactual, and does it carefully: a stated baseline — the most expensive model in the hardest tier the router configures — adjusted for a warm cache, with the classifier’s own cost subtracted and a signed result that can admit routing lost money. It is in a proxy you can self-host in production for nothing, under MIT, with an enterprise carve-out we have not established this feature falls outside.

The difference is where the number goes. LiteLLM’s savings figure reaches the operator — a daily-activity rollup, a cost dashboard, a column in the spend log — and is in no response header and no response body, so the caller who made the request cannot read it.

OpenRouter went the other way, and got further than most people realise. Opt into a header and the response names the routing strategy, summarises the decision in a line, and lists the candidate endpoints it considered with a flag on the one it picked. The candidates carry no prices, so you can see it chose among five and not what the other four would have charged — but it is more disclosure about a routing decision than anyone else on this page offers, ourselves included.

Portkey declines the question by design: you write the rules, so there is no decision to explain. Its cost accounting is careful, including overrides for rates you negotiated yourself, and it lives in the dashboard — the inference response carries exactly four headers and none of them is money.

So the claim that survives

Two of the three route, one of them free, and LiteLLM measures savings well. What is left is narrow and, as far as we can verify, still ours:

The counterfactual belongs on the request that caused it, in the response the caller already has.

Where the counterfactual exists at all above, it is reporting — reviewed later, in aggregate, by whoever pays the bill. In the response path it is data instead: available to the code that made the call, at the moment it made it.

Two qualifications on that receipt

Those headers are on a buffered response. Set stream: true and they are gone — not by choice: the headers are written before the provider has reported a single token. The figures move to the final frame of the stream, and the metering docs say which path carries what.

On auto there is no model you asked for, so the like-for-like comparison above does not exist. The baseline becomes the most expensive model your plan allows — what you would have paid had you asked for the best one — and x-lobstack-baseline-reason reads plan_ceiling instead of named. It is a real subtraction between two real prices, and it is also the most flattering number available to us, which is why it is labelled and why the CLI prints “vs ceiling” rather than “saved”.

Watch the router score a prompt and price the decision before you send anything.

Every claim about another vendor here was checked against their own documentation on 2026-09-10 and is linked from that vendor’s comparison page. This category moves faster than the pages written about it; if you are reading this long after that date, check them yourself.