Skip to content
Go back

OpenRouter vs LiteLLM

· Updated:
By SumGuy 17 min read
OpenRouter vs LiteLLM
Contents

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 fails

Note 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

DimensionOpenRouterLiteLLM
Setup time5 minutes30 minutes (Docker + config)
Cost model5.5% platform fee on credit top-upsZero margin (direct API costs)
Inference markupNone (provider list price)None (provider list price)
InfrastructureHosted by OpenRouterYou run it, at every tier
Routing flexibilityLimited (auto / manual select)Unlimited (YAML rules)
Fallback chainsBasic (one provider at a time)Full control (custom rules)
Budget controlsBasic dashboardGranular per-model/user limits
ObservabilityDashboard + basic logsFull audit trail, integratable
Provider count500+ models from 80+ providersAll (you control the keys)
Free tier25+ models, 50 reqs/dayFree, but you supply provider keys
Compliance/auditLimitedFull control
Dependency riskYou rely on OpenRouter, now Stripe-ownedYou rely on your infrastructure
Best forTeams, SaaS, quick prototypesHome 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:

InferencePlatform feeTotal
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:

docker-compose.yml
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: 3

LiteLLM Config (YAML)

Drop this in your config.yaml file alongside the compose:

config.yaml
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_KEY

Three 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:

Terminal window
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GROQ_API_KEY=gsk-...
LITELLM_MASTER_KEY=sk-1234567890abcdef

Then spin it up:

Terminal window
docker-compose up -d

Calling OpenRouter (Direct)

If you go the OpenRouter route, here’s a curl example hitting their API directly:

Terminal window
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:

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 exit

The 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:

Pick LiteLLM if:

Pick both if:


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.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
stunnel vs spiped
Next Post
Immich vs PhotoPrism vs Ente: Self-Hosted Photo Libraries

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts