Skip to content

How to get speed out of OpenRouter

Published . Updated

TL;DR

These are some ways to optimize OpenRouter speed versus cost: :nitro for the fastest live host, sort: "throughput" with max_price to cap what that speed costs, and :batch when nobody is waiting. Or a quick Python function against the endpoints API gets you both at once, ranking hosts by speed then price and pinning the winner.

Same slug, different hosts

If I send a plain model id (z-ai/glm-5.3-flash, openai/gpt-5.2, and the rest), OpenRouter’s default ranking is closer to price / balanced than fastest.

That is visible on a model page. Different companies host the same model. Throughput and latency are not the same from one row to the next.

OpenRouter's providers table: same model, different hosts, different speed

In my own testing on a cached-context chat workload, z-ai/glm-5.3-flash on default routing averaged ~221s per prompt across a 20-prompt run. Output quality was very good. The wait was not. There is a rumor going around that hosts of this model serve it on non-Nvidia accelerators, which would show up as throughput.

Nitro is the routing mode that sorts for speed. If I do not ask for it, I should not expect the fastest host.

The one-line fix: :nitro

Append :nitro to the model id. Same chat-completions endpoint, same headers, no extra fields.

{
  "model": "z-ai/glm-5.3-flash:nitro",
  "messages": [{ "role": "user", "content": "..." }]
}

Nitro does two things:

  1. Sorts eligible providers by throughput (tokens/sec). Same effect as provider.sort: "throughput".
  2. Lets priority-tier endpoints compete. They win only if they are actually fastest, unlike forcing service_tier: "priority".

I pay the tier that served the request. If a priority endpoint wins, I pay priority rates. If it sheds to default, I pay default.

On the same GLM workload above, :nitro averaged ~152s per prompt vs 221s on default routing. A 3-prompt speed check on identical prompts saw 194s vs 282s — about 31% faster. Real speedup. Still slow (more on that below).

Docs: Nitro variant

When I want control instead of a suffix

Throughput, no priority pool. Fastest default endpoints, usually cheaper than Nitro:

{
  "model": "z-ai/glm-5.3-flash",
  "provider": { "sort": "throughput" }
}

Time-to-first-token. I use "sort": "latency" if I care about first byte more than tokens/sec.

Cheap but not slow. Keep price ranking, require a minimum p90 throughput:

{
  "model": "z-ai/glm-5.3-flash",
  "provider": {
    "sort": { "by": "price" },
    "preferred_min_throughput": { "p90": 40 }
  }
}

I pin or skip hosts with provider.only, provider.ignore, or provider.order if one provider is consistently slow.

Speed first, then price

:nitro is max speed. This pick is the fastest host I would actually pay for. OpenRouter’s request object sorts by one key. sort: "throughput" plus max_price is the documented combo: highest tokens/sec, drop anyone above a ceiling. Price is not a second sort key on the wire. It only knocks out outliers. Provider routing says it in those words: use the provider with the highest throughput, as long as it does not cost more than $x/m tokens. The 1 and 2 below are OpenRouter’s own example ceilings, not a live rate. I put in what I will actually pay.

{
  "model": "z-ai/glm-5.3-flash",
  "provider": {
    "sort": "throughput",
    "max_price": { "prompt": 1, "completion": 2 }
  }
}

One thing to know about the ceiling: max_price is per-token USD and OpenRouter’s actual bill can run well above a chars / 4 token estimate on long context. On one of my recent 20-prompt runs, billed cost came in about 66% higher than the char/4 guess. Set the ceiling with headroom or you will filter out hosts you would have been happy to pay.

When two hosts are close on speed, I want the cheaper one to win. That tie-break is not a routing field. I rank the endpoints list myself in Python: throughput_last_30m.p50 first (tokens/sec), then pricing.prompt plus pricing.completion (USD per token, as strings). Throughput on that route is only filled when the request is authenticated.

import requests

def pick_fastest_then_cheapest(model, api_key):
    author, slug = model.split("/", 1)
    r = requests.get(
        f"https://openrouter.ai/api/v1/models/{author}/{slug}/endpoints",
        headers={"Authorization": f"Bearer {api_key}"},
    )
    r.raise_for_status()

    def rank(e):
        tps = (e.get("throughput_last_30m") or {}).get("p50") or 0
        price = float(e["pricing"]["prompt"]) + float(e["pricing"]["completion"])
        return (-tps, price)

    return min(r.json()["data"]["endpoints"], key=rank)["tag"]

Feed the returned tag back into provider.only on the next chat call and the router will pin the winner.

Don’t confuse “batch” with “fast”

:nitro is live inference. :batch (and POST /api/beta/batches) is async, cheaper work. I submit, poll, and wait. Great for overnight evals. Useless if the user is staring at a spinner.

:floor is the other shortcut: cheapest provider, not fastest.

Perceived speed still matters

Routing only picks the host. For a chat UI:

  • Stream the completion so the first tokens show up immediately.
  • Keep prompts tight. A huge RAG context inflates both TTFT and total time no matter which provider wins.
  • Measure wall clock and tokens/sec separately. A long answer on a fast host can still feel slow.

When routing is not enough — switch the model

Routing picks a host of a model. Picking the model is a separate call. On the same 20-prompt cached-context workload I mentioned earlier:

ModelRouteAvg / prompt
GLM 5.3 Flashdefault221s
GLM 5.3 Flash:nitro~152s
Gemini 3 Flashdefault46s

:nitro gave GLM back about a third of its speed. It did not close the gap with a different model on default routing. Same context, same prompts, same judge. The fastest answer was a different slug.

If the base model is the bottleneck, no :nitro, sort, or preferred_min_throughput can rescue it. Benchmark a second slug the same way — with quality and cost checks — and then let the router optimize whatever you ship.

A practical rule

GoalWhat to send
Fastest live chatmodel: "...:nitro"
Fast, skip priority pricingprovider.sort: "throughput"
Fastest under a price ceilingsort: "throughput" + max_price
Lowest costmodel: "...:floor" or provider.sort: "price"
Cheap with a speed floorsort by price + preferred_min_throughput
Overnight / bulkBatch API, not Nitro
Slow model, no routing tweak helpsTry a different slug

Speed on OpenRouter is not a mystery. It is telling the router I care about throughput, paying for it when the fastest endpoint is a priority tier, and switching the model when even the fastest host of it is still too slow.

Reply via email or WhatsApp.