Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 20 additions & 25 deletions components/landing/compare/compare-programs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { Ok, Err, Dim, Faint } from "../zed/terminal";
import { Ok, Err, Warn, Dim, Faint } from "../zed/terminal";

export type TermStep = { term: string; prog: () => unknown[] };
export type CompareRow = { feat: string; them: string; br: string };
Expand All @@ -21,20 +21,21 @@ export const COMPARE_REGISTRY: Record<string, CompareRegistryEntry> = {
term: "deploy · bitrouter",
prog: () => [
["print", <span className="mut">LiteLLM production</span>, 240],
["print", <span><Err>✗</Err> <Dim>postgres · redis · docker-compose · nginx</Dim></span>, 200],
["print", <span><Warn>⚠</Warn> <Dim>python runtime · web framework · datastore</Dim></span>, 200],
["print", <span className="mut">BitRouter</span>, 300],
["print", <span><Ok>✓</Ok> <span className="lbl">bitrouter serve</span> <Faint>· 1 binary · 0 deps</Faint></span>, 320],
["print", <span><Ok>●</Ok> <Dim>ready in</Dim> <span className="lbl">340ms</span></span>, 600],
["print", <span><Ok>✓</Ok> <span className="lbl">bitrouter serve</span> <Faint>· 1 static binary · 0 deps</Faint></span>, 320],
["print", <span className="fnt">{" ↓ no interpreter in the image"}</span>, 600],
["loop", 2000],
],
},
"02": {
term: "latency · 1k req/s",
term: "runtime · where the rust stops",
prog: () => [
["print", <span className="mut">tail latency · 1k concurrent req/s</span>, 240],
["print", <span><span className="ind">LiteLLM </span> <Err>~85ms p99</Err> <Faint>Python GIL</Faint></span>, 240],
["print", <span><span className="ind">BitRouter</span> <Ok>~12ms p99</Ok> <Faint>Rust async</Faint></span>, 320],
["print", <span className="fnt">{" ↓ no GIL · no thread contention"}</span>, 600],
["print", <span className="mut">LiteLLM · rust core for translation</span>, 240],
["print", <span><Warn>⚠</Warn> <Dim>python owns auth · routing · callbacks</Dim></span>, 200],
["print", <span><Warn>⚠</Warn> <Dim>standalone rust server</Dim> <Faint>beta · fewer routes</Faint></span>, 320],
["print", <span className="mut">BitRouter · rust end to end</span>, 240],
["print", <span><Ok>✓</Ok> <Dim>one binary</Dim> <Faint>· nothing in a sidecar</Faint></span>, 600],
["loop", 2000],
],
},
Expand All @@ -43,31 +44,25 @@ export const COMPARE_REGISTRY: Record<string, CompareRegistryEntry> = {
prog: () => [
["print", <span><Dim>configuring policy</Dim> <span className="lbl">default</span></span>, 320],
["print", <span><Ok>✓</Ok> <Dim>MCP gateway</Dim> <Faint>active</Faint></span>, 180],
["print", <span><Ok>✓</Ok> <Dim>ACP gateway</Dim> <Faint>active</Faint></span>, 180],
["print", <span><Ok>✓</Ok> <Dim>KYA identity</Dim> <Faint>active</Faint></span>, 180],
["print", <span><Ok>✓</Ok> <Dim>injection detect</Dim> <Faint>active</Faint></span>, 180],
["print", <span><Ok>✓</Ok> <Dim>x402 payments</Dim> <Faint>active</Faint></span>, 420],
["print", <span><Err>LiteLLM:</Err> <Dim>none of the above</Dim></span>, 600],
["print", <span><Warn>LiteLLM:</Warn> <Dim>MCP only</Dim></span>, 600],
["loop", 2000],
],
},
},
rows: [
{ feat: "Open source", them: "✓ MIT", br: "✓ Apache 2.0" },
{ feat: "Single binary (no dependencies)", them: "✗ Postgres + Redis + Docker", br: "✓" },
{ feat: "Agent gateway (MCP / ACP / Skills)", them: "✗", br: "✓ built-in" },
{ feat: "Autonomous agent payments (x402)", them: "✗", br: "✓" },
{ feat: "KYA agent identity", them: "✗", br: "✓" },
{ feat: "Prompt injection detection", them: "✗", br: "✓" },
{ feat: "Multi-provider failover mid-run", them: "✗ manual config", br: "✓ automatic" },
{ feat: "Routing overhead", them: "✗ ~20ms+ (asyncio overhead)", br: "✓ ~5ms p50" },
{ feat: "Per-run cost attribution", them: "✗", br: "✓" },
{ feat: "BYOK support", them: "✓", br: "✓" },
{ feat: "Platform fee (hosted option)", them: "— self-host only", br: "✓ none · 0% markup" },
{ feat: "Provider & endpoint coverage", them: "✓ 100+ providers, embeddings / rerank / audio", br: "⚠ SOTA-tier chat, extend by PR" },
{ feat: "What you deploy", them: "⚠ Python runtime + web framework + database", br: "✓ one static binary, no deps" },
{ feat: "Agent gateway (MCP / ACP / Skills)", them: "⚠ MCP only", br: "✓ built-in" },
{ feat: "Routing that learns from outcomes", them: "✗ static config", br: "✓ act → observe → evaluate → learn" },
{ feat: "Hosted option", them: "⚠ Enterprise, quote-only", br: "✓ self-serve, no sales call" },
],
tradeoffs: [
"You want a Python-native library embedded directly in your application code with SDK-level call hooks",
"Your stack is pure Python and you need framework callbacks (async generators, middleware)",
"You're using LiteLLM's extensive provider mapping for non-standard model endpoints",
"You need breadth on day one — 100+ providers plus embeddings, rerank, and audio endpoints",
"You want the library, not the proxy: in-process Python calls with SDK-level hooks and middleware",
"You need enterprise checkboxes shipped today — SSO/SAML, audit logs, RBAC, compliance certifications",
],
},

Expand Down
36 changes: 28 additions & 8 deletions content/docs/(guide)/overview/bitrouter-vs-litellm.mdx
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
---
title: BitRouter vs LiteLLM
description: LiteLLM is a Python-native library that lives inside your app; BitRouter is a single Rust binary with zero dependencies and ~7× better tail latency under load. An honest side-by-side.
description: LiteLLM is the all-in-one AI gateway with the widest provider coverage in the category. BitRouter is a focused, extensible one built around a loop that learns. An honest side-by-side.
---

LiteLLM is the popular MIT-licensed, Python-native option — and if you want a library that lives *inside* your application with SDK-level call hooks, that's exactly its strength. The differences show up in operations and latency.
LiteLLM is the default choice for good reason. It's MIT-licensed, it speaks to 100+ providers, and whatever gateway feature you're looking for, it probably already has a config key for it. We're not going to pretend otherwise. If you want a Python library that lives *inside* your process — `from litellm import completion`, no proxy at all — BitRouter has no answer for that, and it isn't close.

## Operations and latency
So the useful question isn't which is better. It's whether you want a box with everything in it, or a small thing that gets better at its job.

A production LiteLLM deployment typically means Postgres, Redis, and Docker Compose to run the proxy, and its Python runtime carries the GIL: under concurrent load, tail latency climbs to **~85ms p99**. BitRouter is a single binary with zero dependencies (`bitrouter serve`, ready in ~340ms) and a Rust async core that holds **~12ms p99** at 1k req/s.
## All-in-one proxy vs. a router that learns

## What each one routes
LiteLLM's bet is coverage: every provider, every gateway feature, in one proxy you configure. It works. Ours is the opposite, because we don't think the interesting problem is feature count — it's that routers don't learn. Every gateway on the market forwards your thousandth call exactly the way it forwarded your first. BitRouter wraps your agent loop in a second one — [act → observe → evaluate → learn](/docs/overview/what-is-bitrouter) — and folds what it observes back into the routing policy. Cheaper paths that still reached the goal get promoted; ones that didn't get escalated back.

On agent features the gap is structural: an MCP/ACP gateway, KYA identity, injection detection, and autonomous x402 payments are built into BitRouter and absent from LiteLLM. LiteLLM routes model calls; BitRouter routes *agent runs* — and wraps them in an [act → observe → evaluate → learn](/docs/overview/what-is-bitrouter) loop that tightens routing every run, instead of forwarding to a static route.
"Minimal" here means minimal to *operate*, not minimal in ambition. An MCP gateway, an ACP gateway for sub-agents, KYA identity, and x402 payments are all in the box — but they serve that one loop, and it's still one binary and one `bitrouter.yaml`. Anything we don't ship, you add: the [provider registry](/docs/gateway-and-routing/provider-selection) takes a YAML file and a PR.

<CompareTable slug="bitrouter-vs-litellm" />

## LiteLLM is the right call when
## Self-serve cloud vs. enterprise-only

You want a Python-native library embedded directly in your app code, your stack is pure Python and you rely on framework callbacks (async generators, middleware), or you lean on LiteLLM's extensive provider mapping for non-standard model endpoints. If you'd rather move the routing out of your process, the [migration guide](/docs/guides/migrate-from-litellm) covers it.
LiteLLM's hosted offering is an enterprise product: quote-only, sized to your request volume, priced through a sales conversation. SSO, audit logs, RBAC, and support SLAs live behind it. If you're a two-person team, the only real option is self-hosting it yourself.

[BitRouter Cloud](/docs/overview/quickstart) is self-serve for anyone with a credit card — no call, no minimum, no seat count, and **0% markup** on what providers charge. The Core stays Apache 2.0 and free to self-host forever; bring your own keys or run a local model and you owe us nothing.

## Rust-accelerated vs. Rust-native

A correction to the record first: LiteLLM is no longer a Python-performance story. They've moved their translation hot path to a Rust core and publish benchmarks showing **sub-millisecond** added overhead. That's a real result, and we'd rather say so than pretend it isn't happening.

What remains is where the Rust stops. In LiteLLM's recommended mode it's a bridge inside the Python wheel — Python still owns auth, routing, callbacks, and spend tracking, and you still deploy a Python runtime, a web framework, and a database. The standalone Rust server is beta and covers fewer routes. Their roadmap puts the full transition at the end of 2026, and even that endgame runs Python in a sidecar for plugins, guardrails, and SSO by design. BitRouter is one statically linked binary: `bitrouter serve`, cold-starting in well under a second and holding tens of megabytes resident, with no interpreter and no web framework in the image.

That gap matters less for latency than you'd think, and more for what you inherit. A Python proxy inherits its framework's vulnerabilities — 2026 saw a critical unauthenticated RCE in LiteLLM built by chaining a command-injection bug in its MCP endpoints with a host-header bypass in an upstream Python web framework. Both were disclosed and patched properly, and we're not claiming immunity: our MCP gateway executes tools too, and no language prevents a design bug. We're claiming a smaller blast radius — no interpreter loading code at runtime, no transitive framework chain to inherit a bypass from, and a lot less of it to audit.

## Use LiteLLM when

**You need breadth on day one.** LiteLLM covers 100+ providers plus embeddings, rerank, audio, and image endpoints out of the box. BitRouter deliberately ships deep support for SOTA-tier chat models and extends by PR — if you need Bedrock's fourteenth variant or a rerank endpoint this afternoon, that's LiteLLM.

**You want the library, not the proxy.** LiteLLM's real superpower is being importable — in-process calls with SDK-level hooks, async generators, and framework middleware. If your stack is pure Python and you want the gateway inside your app rather than next to it, use LiteLLM.

**You need enterprise checkboxes today.** SSO/SAML, audit logs, RBAC, compliance certifications, support SLAs — LiteLLM Enterprise has them shipped and we're still building ours. If you like where we're going and have enterprise requirements, [talk to us](https://cal.com/bitrouter/founder-call) — that roadmap is very much open to being shaped.

Already running LiteLLM and want to try the other shape? The [migration guide](/docs/guides/migrate-from-litellm) keeps your provider mappings.

## Next steps

Expand Down
20 changes: 12 additions & 8 deletions content/docs/guides/migrate-from-litellm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ LiteLLM is a Python SDK and self-hosted proxy for unifying access to 100+ LLM pr

| | LiteLLM Proxy | BitRouter |
|---|---|---|
| **Runtime** | Python | Rust (single static binary) |
| **Production deps** | Postgres + Redis + Docker/K8s | None |
| **Deployment modes** | Self-hosted only | Local binary **or** hosted (`api.bitrouter.ai`) — same OpenAI-compatible endpoint |
| **Runtime** | Python host with a Rust core for translation | Rust (single static binary) |
| **Production deps** | Python runtime + web framework + Postgres/Redis | None |
| **Deployment modes** | Self-hosted, or Enterprise cloud (quote-only) | Local binary **or** self-serve hosted (`api.bitrouter.ai`) — same OpenAI-compatible endpoint |
| **Provider & endpoint coverage** | 100+ providers, plus embeddings / rerank / audio | SOTA-tier chat models; extend by PR |
| **Agentic auth & payment** | None | x402 / MPP autonomous payment (cloud mode) |
| **Design focus** | All-in-one LLM gateway: admin UI, virtual keys, budgets, with agent gateways added alongside | Agent-first proxy: MCP / ACP / Skills, agent firewall, agentic payment as the core surface |
| **Agent protocol surface** | MCP, A2A, Skills, CLI — bolted onto the horizontal gateway | MCP, ACP, Skills, CLI — the product, not an add-on |
| **Design focus** | All-in-one LLM gateway: admin UI, virtual keys, budgets, with agent gateways alongside | Agent-first proxy: MCP / ACP / Skills, agent firewall, agentic payment as the core surface |
| **License** | MIT (SDK) / paid enterprise tier | Apache 2.0 throughout |

## Two things worth highlighting
Expand All @@ -29,7 +29,7 @@ This matters when your agent should *pay per request* without you provisioning k

### 2. Agent-native, not all-in-one

LiteLLM has shipped MCP, A2A, Skills, and a CLI alongside its horizontal LLM gateway — virtual keys, team budgets, spend dashboards, admin UI all included. BitRouter inverts that: agent primitives *are* the product, the team-admin stack is intentionally minimal. What you get on the BitRouter surface:
LiteLLM has shipped MCP, A2A, Skills, and a CLI alongside its horizontal LLM gateway — virtual keys, team budgets, spend dashboards, and an admin UI all included. BitRouter inverts the emphasis: agent primitives *are* the product, and the team-admin stack is intentionally minimal. What you get on the BitRouter surface:

- [MCP gateway](/docs/gateway-and-routing/mcp-gateway) — proxy MCP servers so agents discover tools across hosts.
- [ACP gateway](/docs/gateway-and-routing/acp-gateway) — first-class support for the Agent Client Protocol used by Claude Code, Codex, OpenCode, and others.
Expand Down Expand Up @@ -82,7 +82,7 @@ Fallbacks and provider selection that you'd configure with `litellm.Router` move

### From the LiteLLM Proxy

The proxy migration replaces the Python process + Postgres + Redis with a single binary. Install and launch:
The proxy migration replaces the Python host and its datastores with a single binary. Install and launch:

<Tabs items={['Before (LiteLLM Proxy)', 'After (BitRouter local)']}>
<Tab value="Before (LiteLLM Proxy)">
Expand Down Expand Up @@ -129,7 +129,11 @@ To skip the local proxy entirely, point clients at `https://api.bitrouter.ai/v1`

## What BitRouter intentionally doesn't ship

To set expectations honestly: BitRouter does not ship a built-in admin UI for team/user budgets, virtual-key generation by API, or a spend analytics dashboard at parity with LiteLLM Enterprise. Per-workspace key scoping in cloud mode and env-var-scoped keys in local mode cover the common cases, but if your migration depends on per-user virtual keys with quotas enforced inside the proxy, plan for that gap or stay on LiteLLM for those workloads.
To set expectations honestly, two gaps are worth checking before you start.

**Non-chat endpoints.** LiteLLM covers embeddings, rerank, audio, and image endpoints across 100+ providers out of the box. BitRouter ships deep support for SOTA-tier chat models and extends by PR to the [provider registry](/docs/gateway-and-routing/provider-selection). If your workload leans on embeddings or rerank today, either add them to the registry first or keep those calls on LiteLLM.

**Team administration.** BitRouter does not ship a built-in admin UI for team/user budgets, virtual-key generation by API, or a spend analytics dashboard at parity with LiteLLM Enterprise. Per-workspace key scoping in cloud mode and env-var-scoped keys in local mode cover the common cases, but if your migration depends on per-user virtual keys with quotas enforced inside the proxy, plan for that gap or stay on LiteLLM for those workloads.

## Migration checklist

Expand Down
1 change: 1 addition & 0 deletions lib/docs-sync/constants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const COMPONENT_WHITELIST = [
"ProvidersTable",
"CalInline",
"CompareTable",
"CompareTerminal",
];

// Where synced authored docs land (will be gitignored at the Plan B cutover).
Expand Down
Loading