What changed on Oct 28
Until now the default router sent most traffic to the provider with the lowest input-token price, and a failed request went to the next cheapest.1 The new default scores each provider endpoint on a "Routing Cost": effective price, time spent waiting (throughput and time to first token), and the expected cost of retries when a provider errors, rate limits or returns unusable output.1 If 1 in 5 tries fails, OpenRouter counts 1.25 tries per good answer.1
Effective price is computed from recent measured traffic, including the provider's real cache hit rate and the model's usual input/output mix, so it can differ a lot from list price.1 Traffic is shared among providers inside a competitive edge, every provider keeps a trickle, a failing provider gets less, and a cap spills load once a provider starts returning 429s.1
What OpenRouter reports, and what it does not tell you
In a switchback experiment over one week, 24 million requests and a sample of open-source models, OpenRouter reported these results for new versus legacy routing:1
| Measure | Legacy | New |
|---|---|---|
| TTFT p50 | 1,007 ms | 837 ms |
| Whole request p95 | 41.5 s | 34.9 s |
| Requests hitting a 429 | 7.1% | 3.8% |
| Cost per M tokens | $0.301 | $0.324 |
Treat these as direction, not a forecast. Your model, prompt size, cache pattern and streaming mix decide where you land. The cost line is the one to watch: OpenRouter says the new router can pick a faster or more reliable provider over the cheapest one.1
Which settings bypass the new router
The rule is per request, so audit what your clients actually send.
| Request sets | Behavior |
|---|---|
| Nothing | New router1 |
provider.sort (price, throughput, latency) | That sort replaces the new algorithm1 |
provider.order | Bypasses the new router; providers tried in the order given1 |
provider.only / provider.ignore | Filters candidates; new router picks among the rest1 |
:floor on the model slug, or account default sort set to price | Price-only routing1 |
An ongoing conversation is pinned to its first provider so the prompt cache stays warm, and falls back automatically if that provider becomes unavailable.1 The post does not say how a conversation is identified, so check with your own client whether your multi-turn traffic really sticks.
Pin it, and see what served
A deterministic request names the order, turns off fallbacks if you want a hard failure, and asks for routing metadata:
import requests
r = requests.post(
"https://openrouter.ai/api/v1/chat/completions",
headers={
"Authorization": "Bearer " + KEY,
"X-OpenRouter-Metadata": "enabled",
},
json={
"model": "vendor/model",
"messages": [{"role": "user", "content": "ping"}],
"provider": {
"order": ["provider-a", "provider-b"],
"allow_fallbacks": True,
"require_parameters": True,
},
},
timeout=60,
)
meta = r.json().get("openrouter_metadata", {})
print(meta.get("attempt"), meta.get("attempts"), meta.get("endpoints"))The header surfaces openrouter_metadata with the selected endpoint, candidates considered, and attempt (above 1 means earlier attempts failed and fell back).2 For streams it arrives on the final chunk; cache hits never carry it.2 The fields order, allow_fallbacks, require_parameters, zdr, only and ignore are documented provider-object fields.3 Provider slugs above are placeholders.
What to re-check
- Serving provider. Sample
openrouter_metadataand count requests per provider before and after Oct 28. - Cost per request. Compare your own spend per request against the week before; effective price follows cache hits and output mix, not list input price.1
- Tool calls and structured output. The router's quality check today is mainly whether tool calls come back well formed.1
require_parametersis false by default, so set it where a provider ignoring a parameter would break you.3 - Data rules. Confirm
zdr,data_collectionandonlyare set on requests that need them rather than assumed.3 - Timeouts. A faster median does not change your tail; re-measure p95 with streaming on.
- Double retries. OpenRouter retries a failed try with the next ranked provider.1 If your own gateway also retries, a single outage can multiply attempts; cap one layer.
Test it against your own rules
Replay a fixed prompt set in three arms: default, sort: "price", and your order. Run each long enough that the trickle traffic to weaker providers shows up, compare latency, cost per request and tool-call validity, and keep the arm that meets your SLO. Repeat after a provider incident, since the router reacts in real time.1
If part of your traffic goes through INFRO routes, those routes use priority or weighted targets over your own connections, retry before the response starts, and never restart a stream that has begun.4 INFRO's request log records latency and estimated provider cost per request, which gives you the before/after series on your side; the upstream provider behind OpenRouter still comes from OpenRouter's metadata.
