The Multi-Model Problem
OpenRouter wins when you want zero ops burden and a shared team API key, and LiteLLM wins the moment you want zero margin and full control over routing and budgets.
You’ve got Claude running on Anthropic’s API. GPT on OpenAI. Llama on Groq. Maybe some local open source stuff. And your app needs to talk to all of them without embedding each provider’s SDK directly in your code. Because vendor lock-in is for people who enjoy pain.
What if Claude goes down? What if OpenAI’s rates spike? What if you want to A/B test which model actually gives better results for your use case? These are the kinds of 2 AM questions that keep infrastructure people awake.
This is where request routing comes in. Instead of hardcoding OpenAI’s endpoint in your app, you point your code at a gateway, a single API that knows how to talk to every provider you care about. When one provider hiccups, the gateway automatically tries the next one. When pricing changes, you adjust the routing rules once, not in six different services.
The two heavyweight contenders are OpenRouter and LiteLLM. Same problem, wildly different philosophies. Let’s dig in.
OpenRouter: Hosted Gateway, Hands Off
OpenRouter is the sign-up-and-go option. You sign up, get an API key, and suddenly your code can talk to 500+ models through a single endpoint. No infrastructure to run. No Docker compose files. No monitoring dashboards you built yourself at midnight.
How it works: OpenRouter sits between your app and every major LLM provider. You make one HTTP request to OpenRouter’s API. It routes your request to whichever provider you specified, or it auto-selects based on your criteria (cheapest, fastest, highest quality). Then it streams the response back to you.
It’s the cloud SaaS play, hosted by OpenRouter’s team. Worth being precise about the money, because a lot of people get this wrong: OpenRouter does not mark up inference. You pay the provider’s listed rate per token. What you pay for is the credit purchase, a 5.5% platform fee on pay-as-you-go top-ups (as of August 2026). Same tokens, same price, with a cut taken when you load the wallet.
The OpenRouter Upside
Setup is trivial. Sign up, drop an API key in your .env, update your client library to point to https://openrouter.ai/api/v1 instead of https://api.openai.com/v1. Done. If your app already uses the OpenAI Python SDK, you literally change three lines:
from openai import OpenAI
client = OpenAI( api_key=os.getenv("OPENROUTER_API_KEY"), base_url="https://openrouter.ai/api/v1",)
response = client.chat.completions.create( model="openrouter/auto", # OpenRouter picks the best match messages=[{"role": "user", "content": "Explain Docker to me"}],)Automatic provider fallback. If you specify openrouter/auto, OpenRouter uses their own heuristics to pick a provider. Model overloaded? They try the next cheapest alternative. Provider outage? They route around it. You don’t have to think about it.
Model marketplace. OpenRouter surfaces 500+ models from 80+ providers in one catalog. Anthropic, OpenAI, Meta, Cohere, Mistral, Groq, Together, even obscure open source models. No account juggling. One bill. One dashboard showing spend across all of it.
A real free tier. 25+ free models across 4 providers, capped at 50 requests a day, no platform fees. Enough to wire up an integration and see if the idea works before you put a card in.
No infrastructure. You’re not responsible for keeping a proxy alive. No Docker image to patch. No Python dependencies to upgrade. OpenRouter’s team handles the plumbing. Your ops load is zero.
Team-friendly. Slap an OpenRouter key on a shared .env and everyone’s good. No individual provider credentials scattered across five different services. That alone is worth something when Sarah leaves the team and you realize her API keys are still live everywhere.
The OpenRouter Downside
You pay the platform fee. 5.5% on every pay-as-you-go credit top-up, as of August 2026. There are no volume discounts on the self-serve plan, so that percentage does not soften as you scale. Bringing your own provider keys (BYOK) is free up to $25,000 of list-price inference a month, then costs 5% of what the same call would have cost on OpenRouter. Enterprise raises the BYOK allowance to $200,000 a month and opens the door to fee discounts, which means talking to sales. For a solo home lab, the 5.5% is pocket change. For a startup pushing real traffic, it’s a line item.
Routing rules are limited. You can specify a model or use openrouter/auto, but you can’t write fancy conditional logic like “if response latency > 5 seconds, failover to this provider” or “if we’ve hit 80% of our budget, switch to cheaper models.” It’s their rules, not yours.
Less observability. You get a dashboard showing what you spent on which models, but you don’t get deep visibility into why a request went to Provider A instead of Provider B. If you need audit logs and detailed routing decisions for compliance, you’re limited.
Vendor lock-in (ironic). You’re trying to avoid vendor lock-in by using a multi-model gateway. But you’ve introduced a new vendor: OpenRouter. If they go down (rare, but possible), your app breaks. If they change pricing or deprecate a model, you have to adapt. It’s distributed risk, but it’s still risk. And that risk got more interesting in August.
Stripe Bought OpenRouter. Does That Change the Pick?
On 19 August 2026, Stripe announced it had agreed to acquire OpenRouter. CNBC put the price above $7 billion. Stripe’s own newsroom framed it as helping businesses “optimize token routing and usage,” and named NVIDIA, Zoom, and Lovable as existing OpenRouter customers. Patrick Collison’s quote was about tokens being “the central currency for companies building with AI,” which tells you exactly how Stripe is thinking about this: billing infrastructure, extended to inference.
So does it change the recommendation? Not today. Prices haven’t moved, the API hasn’t changed, and Stripe is not a company with a history of buying developer tools and immediately setting them on fire. If you’re happily on OpenRouter, keep going.
What it changes is the shape of the bet you’re making. Before August, OpenRouter’s incentive was simple: stay the neutral router, because neutrality was the entire product. Now the router is owned by a payments company whose interest is in the transaction layer. That’s not a prediction of doom. It’s a reminder that the “neutral gateway” you adopted to escape vendor lock-in is itself a vendor, and vendors get acquired by other vendors with different priorities. The reason the LiteLLM column exists is that nobody can buy your Docker container.
The practical move is boring and cheap: keep your integration OpenAI-compatible. Both of these tools speak that dialect, which means switching between them is a base_url change and a key swap, not a rewrite. Build it that way and the acquisition news becomes something you read rather than something you respond to.
LiteLLM: Self-Hosted Proxy, Full Control
LiteLLM is the DIY option. You run the proxy yourself, in Docker, on your home lab server, wherever. You own the routing decisions. You own the fallback chains. You own the observability. You also own the operational headaches.
How it works: LiteLLM is a lightweight Python proxy that translates requests from your app into calls to any LLM provider. It has a YAML config file where you define which providers to use, how to route between them, fallback rules, budget limits, caching behavior, cost tracking. Your app makes one request to your local LiteLLM instance. LiteLLM figures out where to send it.
It’s the self-hosted play. You control everything. You pay zero margin because you’re directly hitting provider APIs with your own credentials.
The LiteLLM Upside
Zero margin. You have accounts with Anthropic, OpenAI, Groq, whatever. LiteLLM uses your credentials directly. You pay exactly what each provider charges, no markup. Over time, that math is compelling.
Complete routing control. Define fallback chains: “Try Groq first because it’s stupid cheap. If that fails, try Together. If that fails, hit Claude with an immediate=true flag because you need quality.” You write YAML rules that match your exact use case.
model_list: - model_name: "fast" litellm_params: model: "groq/openai/gpt-oss-120b" api_key: os.environ/GROQ_API_KEY - model_name: "smart" litellm_params: model: "anthropic/claude-opus-5" api_key: os.environ/ANTHROPIC_API_KEY
router_settings: fallbacks: [{"fast": ["smart"]}] # Groq first, Claude if it failsNote the fallbacks key lives under router_settings and takes a list of
single-key maps. Get that shape wrong and the proxy starts fine, then quietly
never fails over.
Budget controls. Set spend limits per model, per user, per API key. Hit your budget? LiteLLM blocks requests and you find out before your credit card declines. Audit trail is there. No surprises.
Caching. LiteLLM can cache prompt+completion pairs, so repeated identical requests don’t hit the provider again. Huge for dev workflows. Anthropic’s prompt caching is supported natively.
Observability. Every request gets logged. Latency, cost, provider, success/failure, why it failed. You can hook into Datadog, New Relic, Langfuse, or ingest logs into your own Elasticsearch stack. Full audit trail, full control.
A commercial tier exists, and it does not save you the ops. LiteLLM Enterprise adds SSO and SCIM, RBAC, audit logs on every request, tag-based spend tracking, secret-manager integration, and 24/7 support with response SLAs (one hour for a total production outage). What it does not add is somebody else running the thing. Enterprise is explicitly self-hosted, including air-gapped deployment. That’s the point of it for regulated shops, and it’s also the catch if you came looking for a managed option: there isn’t one. With LiteLLM, you run the proxy at every tier.
The LiteLLM Downside
You run it. It’s a service you have to keep alive. Deploy it to Docker, write a systemd unit, stick it on your Proxmox homelab VM, whatever. But it’s your responsibility. It needs monitoring. It needs logs. If it crashes at 2 AM, your app stops working.
Setup is harder. You need provider API keys for every service you want to route to. You need to write YAML config. You need to think about how to run the proxy (Docker? Kubernetes? systemd?). There’s no one-click signup.
Debugging fallback chains is messy. When a request fails and bounces through three fallback providers before succeeding, you need to dig through logs to understand why. OpenRouter abstracts that away; LiteLLM gives you full visibility but also full responsibility.
Operator burden. Managing secrets is your problem. Scaling the proxy is your problem. Keeping dependencies patched is your problem. For a solo home lab, that’s fine. For a team, you’re asking someone to own this as a system.
Head-to-Head Comparison
| Dimension | OpenRouter | LiteLLM |
|---|---|---|
| Setup time | 5 minutes | 30 minutes (Docker + config) |
| Cost model | 5.5% platform fee on credit top-ups | Zero margin (direct API costs) |
| Inference markup | None (provider list price) | None (provider list price) |
| Infrastructure | Hosted by OpenRouter | You run it, at every tier |
| Routing flexibility | Limited (auto / manual select) | Unlimited (YAML rules) |
| Fallback chains | Basic (one provider at a time) | Full control (custom rules) |
| Budget controls | Basic dashboard | Granular per-model/user limits |
| Observability | Dashboard + basic logs | Full audit trail, integratable |
| Provider count | 500+ models from 80+ providers | All (you control the keys) |
| Free tier | 25+ models, 50 reqs/day | Free, but you supply provider keys |
| Compliance/audit | Limited | Full control |
| Dependency risk | You rely on OpenRouter, now Stripe-owned | You rely on your infrastructure |
| Best for | Teams, SaaS, quick prototypes | Home labs, full control, cost-sensitive |
The Real Cost Question
Because the fee sits on the top-up rather than on the tokens, the math is simpler than people expect. Whatever your inference bill would have been, add 5.5%.
Work it through with Claude Opus 5, which lists at $5 per 1M input tokens and $25 per 1M output tokens (August 2026). Say a busy month is 10M input and 2M output:
| Inference | Platform fee | Total | |
|---|---|---|---|
| LiteLLM (direct keys) | $100.00 | $0 | $100.00 |
| OpenRouter (PAYG) | $100.00 | $5.50 | $105.50 |
Difference: $5.50/month. At ten times that volume it’s $55/month, and it keeps scaling in a straight line because self-serve has no volume discounts.
Two things worth noticing. First, that gap is smaller than most people assume, because the “OpenRouter takes a cut of every token” story is wrong. Second, it is entirely real money that buys you nothing except not having to run a container. Whether $5.50 or $55 a month is a good price for that depends on what an hour of your time is worth and how much you enjoy patching Python dependencies.
One correction worth making if you read this article before August 2026: it used to price Claude Opus at $15 per 1M input tokens. That was right for Opus 4 and 4.1, both since retired. Opus 5 lands at $5, and Sonnet 5 at $2 in and $10 out is the better default for routing work anyway.
Docker Compose Setup (LiteLLM)
If you want to run LiteLLM locally, here’s a working compose file:
services: litellm: image: ghcr.io/berriai/litellm:latest container_name: litellm-proxy ports: - "8000:8000" environment: - OPENAI_API_KEY=${OPENAI_API_KEY} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - GROQ_API_KEY=${GROQ_API_KEY} volumes: - ./config.yaml:/app/config.yaml command: litellm --config /app/config.yaml --port 8000 restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 5s retries: 3LiteLLM Config (YAML)
Drop this in your config.yaml file alongside the compose:
model_list: - model_name: "workhorse" litellm_params: model: "openai/gpt-4o" api_key: os.environ/OPENAI_API_KEY rpm: 3500 # per-deployment rate limit
- model_name: "workhorse-fast" litellm_params: model: "groq/openai/gpt-oss-120b" api_key: os.environ/GROQ_API_KEY
- model_name: "workhorse-smart" litellm_params: model: "anthropic/claude-opus-5" api_key: os.environ/ANTHROPIC_API_KEY
router_settings: redis_host: "" # Optional: set for shared state across replicas timeout: 30 fallbacks: - {"workhorse": ["workhorse-fast", "workhorse-smart"]}
litellm_settings: # Used only when a request blows past the model's context window context_window_fallbacks: - {"workhorse": ["workhorse-smart"]} # Catch-all if a model group is misconfigured entirely default_fallbacks: ["workhorse-smart"]
general_settings: master_key: os.environ/LITELLM_MASTER_KEYThree schema details that cost people an afternoon. Plain fallbacks goes under
router_settings. The specialized ones (context_window_fallbacks,
content_policy_fallbacks, default_fallbacks) are accepted in either
router_settings or litellm_settings, so pick one block and stay there rather
than scattering them. All of them take a list of single-key maps, not a nested
model_name / fallbacks pair. And rate limits (rpm, tpm) go inside the
deployment’s own litellm_params, not in a separate block. LiteLLM will happily
boot with an unrecognized top-level key and simply not route the way you think
it does, which is the worst failure mode available: silent.
Set your .env file:
OPENAI_API_KEY=sk-...ANTHROPIC_API_KEY=sk-ant-...GROQ_API_KEY=gsk-...LITELLM_MASTER_KEY=sk-1234567890abcdefThen spin it up:
docker-compose up -dCalling OpenRouter (Direct)
If you go the OpenRouter route, here’s a curl example hitting their API directly:
curl -X POST https://openrouter.ai/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -d '{ "model": "anthropic/claude-opus-5", "messages": [ { "role": "user", "content": "Explain how LiteLLM routing works in simple terms." } ], "max_tokens": 1024 }'OpenRouter’s response is OpenAI-compatible JSON. Parse the choices[0].message.content and you’re done.
Calling LiteLLM (Local Proxy)
From your app, hit your local proxy exactly like you’d hit OpenAI:
from openai import OpenAI
client = OpenAI( api_key="sk-1234567890abcdef", # Your LITELLM_MASTER_KEY base_url="http://localhost:8000", # Your LiteLLM proxy)
response = client.chat.completions.create( model="workhorse", # LiteLLM figures out the routing messages=[{"role": "user", "content": "What's the deal with Docker?"}], max_tokens=1024,)
print(response.choices[0].message.content)LiteLLM intercepts that request, checks your config, picks the right provider (or falls back), and sends the response back.
Can You Use Both?
Absolutely. LiteLLM can use OpenRouter as one of its providers. So you could have:
- Primary: Direct Anthropic API (no platform fee)
- Fallback 1: Groq (fast, but a narrower catalog)
- Fallback 2: OpenRouter (5.5% on top-ups, but 500+ models and pooled uptime)
If you hit Anthropic’s rate limits or it goes down, LiteLLM tries Groq. If Groq doesn’t have the model you want, it hits OpenRouter as the safety net.
model_list: - model_name: "claude" litellm_params: model: "anthropic/claude-opus-5" api_key: os.environ/ANTHROPIC_API_KEY
- model_name: "claude-via-openrouter" litellm_params: model: "openrouter/anthropic/claude-opus-5" api_key: os.environ/OPENROUTER_API_KEY
router_settings: fallbacks: - {"claude": ["claude-via-openrouter"]} # OpenRouter is the emergency exitThe fallback target has to be a different model_name. Giving both deployments
the same name makes them a load-balanced pool, which is a useful thing but not
the thing you wanted here.
So Which One?
Pick OpenRouter if:
- You want zero ops burden. Sign up, get a key, move on.
- You’re a team and shared API keys matter more than 5.5%.
- You’re prototyping and speed beats cost.
- You don’t want to think about infrastructure at 2 AM.
Pick LiteLLM if:
- You’re running a home lab and you enjoy building infrastructure.
- You have direct accounts with providers and want zero margin.
- You need custom routing logic or granular budget controls.
- You want full observability and audit trails.
- You’re cost-sensitive and run significant volume.
Pick both if:
- You want LiteLLM locally for cost, with OpenRouter as a fallback for reliability.
- You’re running a team where some projects need quick setup (OpenRouter) and others need control (LiteLLM).
The Bottom Line
LiteLLM is the tooling equivalent of running your own home lab Kubernetes cluster: more powerful, more complex, more rewarding if you care about every detail. OpenRouter is the Heroku equivalent: simple, you let them handle it, you pay a premium for the convenience.
Neither is wrong. It depends on whether your idea of fun is “point an API key at something and code” or “build the perfect request routing system with fallback chains that would make a network engineer proud.”
Pick your poison. Either way, you’re no longer a hostage to a single LLM provider.
Common Questions
Is OpenRouter more expensive than going direct to OpenAI or Anthropic?
Per token, no. OpenRouter passes through each provider’s list price with no inference markup, so a million Claude tokens costs the same either way. The extra is a 5.5% platform fee charged when you buy credits on pay-as-you-go. On a $100 monthly inference bill that’s $5.50.
Can I run LiteLLM without Docker?
Yes. pip install 'litellm[proxy]' then litellm --config config.yaml starts
the proxy on port 4000 with no container involved. Docker is the tidier option
for a home lab because it isolates the Python dependencies and restarts cleanly,
but nothing in LiteLLM requires it.
Do I need a database to use LiteLLM’s budget controls?
Yes. Virtual keys, per-team budgets, and spend tracking all persist to Postgres, which is why those features stay dark on a config-only install. Basic routing, fallbacks, and caching work with no database at all. Add Postgres when you need to hand out keys to other people, not before.
How hard is it to switch from OpenRouter to LiteLLM later?
Not hard, if you kept the integration OpenAI-compatible. Both expose the same
chat completions API, so migrating means changing base_url, swapping the key,
and mapping your model names in a YAML file. The real work is collecting
provider API keys and finding somewhere to run the proxy.