Migrate from LiteLLM
Migrating from LiteLLM?Keep the API. Stop running the proxy yourself.
Your app already calls the LiteLLM proxy with an alias in model. Point it at ModelRiver instead, turn each alias and its fallbacks into a workflow, and stop deploying and scaling the proxy.
- BYOK
- no token markup
- Free plan stops at 25,000 requests/month
2 lines of code + 1 workflow
Keep your OpenAI SDK. On the client line, change the base URL and key. On the request line, set model to the name of a workflow.
Step 0: create a workflow in the console with your primary model and backups. Its name is what you send as model.
Before
import os
from openai import OpenAI
client = OpenAI(
base_url="http://0.0.0.0:4000",
api_key=os.environ["LITELLM_MASTER_KEY"],
)
resp = client.chat.completions.create(
model="support-model", # alias from config.yaml
messages=[{"role": "user", "content": "Summarize this ticket."}],
)
print(resp.choices[0].message.content)After
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.modelriver.com/v1",
api_key=os.environ["MODELRIVER_API_KEY"],
)
resp = client.chat.completions.create(
model="support_model", # workflow name
messages=[{"role": "user", "content": "Summarize this ticket."}],
)
print(resp.choices[0].message.content)Before
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://0.0.0.0:4000",
apiKey: process.env.LITELLM_MASTER_KEY,
});
const resp = await client.chat.completions.create({
model: "support-model", // alias from config.yaml
messages: [{ role: "user", content: "Summarize this ticket." }],
});
console.log(resp.choices[0].message.content);After
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.modelriver.com/v1",
apiKey: process.env.MODELRIVER_API_KEY,
});
const resp = await client.chat.completions.create({
model: "support_model", // workflow name
messages: [{ role: "user", content: "Summarize this ticket." }],
});
console.log(resp.choices[0].message.content);Before
curl http://0.0.0.0:4000/chat/completions \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "support-model",
"messages": [{"role": "user", "content": "Summarize this ticket."}]
}'After
curl https://api.modelriver.com/v1/chat/completions \
-H "Authorization: Bearer $MODELRIVER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "support_model",
"messages": [{"role": "user", "content": "Summarize this ticket."}]
}'What maps to what
LiteLLM concepts and where they live in ModelRiver.
| LiteLLM | ModelRiver |
|---|---|
model_list[].model_name alias | Workflow nameSame idea: your code sends a name, the server decides the provider model. Workflow names use letters, digits and underscores. |
litellm_params.model: openai/gpt-4o | Workflow primary provider and modelPicked from the catalog in the Console, or a custom OpenAI-compatible base URL. |
fallbacks: [{"alias": ["b", "c"]}] | Up to 2 backup models on the workflowBackups run on 429, 5xx, 408, 404 and connection errors, including during streaming. |
api_key: os.environ/OPENAI_API_KEY | Provider credential stored in the projectEncrypted at rest and masked in the Console. No environment variables to manage. |
general_settings.master_key | ModelRiver project API keySent as Authorization: Bearer, the same header your OpenAI SDK already uses. |
num_retries, allowed_fails, cooldown_time | No equivalentModelRiver retries only dropped connections, then moves to the next backup. There is no cooldown or circuit breaking. |
Several deployments under one model_name + routing_strategy | No equivalentEach workflow slot is one provider and one model. There is no load balancing. |
request_timeout | Fixed 120-second timeoutNot configurable today. |
context_window_fallbacks, content_policy_fallbacks | No separate chainsOne backup order per workflow, triggered by the error statuses above. |
Map your config
Your fallbacks, output shape and budget move into one named workflow.
Your current LiteLLM request
model_list:
- model_name: support-model
litellm_params:
model: openai/gpt-4o
api_key: os.environ/OPENAI_API_KEY
- model_name: support-backup
litellm_params:
model: anthropic/claude-sonnet-5
api_key: os.environ/ANTHROPIC_API_KEY
router_settings:
fallbacks: [{"support-model": ["support-backup"]}]ModelRiver
The same setup as a ModelRiver workflow
- Primary
- openai/gpt-4o
- Backup 1
- anthropic/claude-sonnet-5
- Backup 2
- google/gemini-3.5-flash (optional)
- Structured output
- Optional JSON schema, saved on the workflow
- Budget
- Optional USD cap per model: hourly, daily, weekly or monthly
- Release
- Draft → Live, roll back any time
Try it with your keys. The Free plan stops at 25,000 requests a month instead of charging overage. Model usage is billed by your provider on your own keys.
Create a workflow freeWhen to stay where you are
LiteLLM may suit you better if any of these matter most.
You need the gateway on your own infrastructure or in your VPC, or prompts must not leave your network. ModelRiver is hosted only and is not self-hostable.
You load-balance across several deployments of one model, or use latency-based or usage-based routing strategies.
You tune retries, cooldowns, timeouts, or separate context-window and content-policy fallback chains.
You call providers outside ModelRiver's 13, or image, audio or Responses API endpoints.
You want to read and change the gateway's source code.
What you gain, what you give up
What you gain
- No proxy to deploy, upgrade or scale. ModelRiver runs the gateway, with a public status page and a 99.9% uptime target (no contractual SLA today).
- Request logs and a per-request timeline with the provider and model used, each failover attempt and a cost estimate. No log database to host.
- Async requests through the native API, with signed webhooks, WebSocket streaming and event-driven backend pipelines.
- USD budgets per workflow model, reset hourly, daily, weekly or monthly. A slot over its cap hands off to the next backup.
- Team access built in: owner, admin, editor and viewer roles, two-factor sign-in, and Draft and Live releases with rollback.
What you give up
- Hosted only: ModelRiver is not open source and is not self-hostable.
- No load balancing across deployments and no routing strategies.
- No configurable retries, cooldowns or timeouts: ModelRiver retries only dropped connections, moves to the next backup, and times out at 120 seconds.
| Topic | LiteLLM | ModelRiver |
|---|---|---|
| How it bills | Open-source proxy (MIT, except the enterprise/ directory) that you run on your own infrastructure, so you pay for hosting and your providers. Enterprise is priced by usage through their sales team. Source (opens in a new tab) · checked | Monthly plans by request volume, with no markup on tokens. Model usage is billed by your provider on your own keys. |
Compared, with sources
- The LiteLLM proxy runs on infrastructure you manage, with Redis to share state across instances. ModelRiver is a hosted service with a public status page and a 99.9% uptime target (no contractual SLA today). Source (opens in a new tab) · checked
- LiteLLM reads its model list and fallbacks from
config.yaml. ModelRiver keeps each workflow as Draft and Live versions with revision history and rollback. Source (opens in a new tab) · checked - LiteLLM is open source, with Enterprise priced by usage; you also pay to host it. ModelRiver bills a plan by request volume, adds no token markup, and its Free plan stops at 25,000 requests a month. Source (opens in a new tab) · checked
- The LiteLLM repository is MIT-licensed outside its
enterprise/directory and runs as a self-hosted proxy. ModelRiver is not open source and is not self-hostable. Source (opens in a new tab) · checked - LiteLLM load-balances deployments that share a
model_name, with routing strategies such as least-busy and latency-based. ModelRiver has no load balancing. Source (opens in a new tab) · checked - LiteLLM has
num_retries, andallowed_failswithcooldown_timeto cool down a failing deployment. ModelRiver retries only dropped connections, then moves to the next backup. Source (opens in a new tab) · checked - LiteLLM sets timeouts with
request_timeout. ModelRiver timeouts are fixed at 120 seconds. Source (opens in a new tab) · checked - LiteLLM supports
fallbacksper model group plus context-window, content-policy and default fallback chains. A ModelRiver workflow has one backup order with up to 2 backups. Source (opens in a new tab) · checked - LiteLLM describes support for 100+ LLMs. ModelRiver supports 13 providers, plus any OpenAI-compatible base URL. Source (opens in a new tab) · checked
Steps to move over
- Step 1
Add your provider keys
Add each key your
config.yamlreads withos.environ/.... Keys are encrypted at rest and masked once saved, so there are no environment variables to manage. - Step 2
Create one workflow per alias your app calls
Primary: the
litellm_params.modelbehind the alias. Backups: the first two models in that alias'sfallbackslist. Name it with underscores, such assupport_model. - Step 3
Replay a few proxy requests against the Draft
Take requests your app sends to the proxy today and run them through the Draft in the Playground. To wire up your app without provider calls, switch the workflow to Testing mode; switch back to Production before you publish.
- Step 4
Publish the workflow Live
API requests run the Live version, so publish before you switch code.
support_modelthen plays the role yourmodel_namealias plays in the proxy. - Step 5
Swap base URL, key and model
Replace the proxy URL with
https://api.modelriver.com/v1, the master key with a ModelRiver API key, and the alias with the workflow name.base_url="https://api.modelriver.com/v1" api_key=os.environ["MODELRIVER_API_KEY"] model="support_model" - Step 6
Keep the proxy as a fallback for a while
Keep your current gateway configured in your code as a fallback until you're confident, then remove it. Leave the proxy running with its current
config.yamland send to it with the old alias if a ModelRiver call fails. - Step 7
Edit the workflow, not the config file
Where you used to change
config.yaml, edit the workflow Draft in the Console, publish it, and roll back to an earlier revision if needed.
Frequently asked questions
Can I keep my hyphenated alias, such as support-model?
Name the workflow support_model. A request for support-model resolves to it, and the x-modelriver-model-resolved-from response header records what you sent. Sending the exact name skips that lookup.
What replaces num_retries and cooldowns?
Nothing configurable. ModelRiver retries a dropped connection, and on 429, 5xx, 408 or 404 it moves to the next backup model. If you rely on cooldowns or tuned retries, that is a reason to stay.
I use the LiteLLM Python SDK, not the proxy. Can it call ModelRiver?
Yes, as an OpenAI-compatible endpoint: litellm.completion(model="openai/support_model", api_base="https://api.modelriver.com/v1", api_key=...). The openai/ prefix tells LiteLLM which API shape to use; ModelRiver sees support_model.
Can I import my config.yaml?
Not automatically. Send it to us with the keys removed and we will reply with the matching workflow setup. Most configs map to one workflow per alias.
Where are my provider keys stored?
In your ModelRiver project, encrypted at rest. Each request uses your key, and your provider bills you directly. ModelRiver adds no token markup.
Can ModelRiver run inside our VPC?
No. ModelRiver is a hosted service. If the gateway has to run on your infrastructure, keep the proxy.
Bring your keys. Keep your SDK.
Start on the Free plan, create a workflow and point your SDK at it.
Send us your models[] request or config.yaml (remove keys first) and we’ll reply with the matching workflow setup. Get help moving
Checked · Report an inaccuracy
Sources
LiteLLM is a trademark of its owner. ModelRiver is not affiliated with, endorsed or sponsored by it.