How it worksLive demoCompareBlogFAQPricingGitHub
Blog / ComparisonOctober 12, 2026
Comparison

Per-user LLM budgets compared: LiteLLM, Helicone, Langfuse, and doing it in-process

Vendor facts were checked against their documentation on October 11, 2026, and may have changed since. LLMBrake is our project, so weigh this accordingly, and tell us if we got something wrong.

If you charge customers a flat monthly price for an AI feature, you eventually need a rule like "each customer can spend at most $X of model cost per month." There are four common places to put that rule. Each makes a real trade-off, and for many teams the honest answer isn't the tool I wrote.

The question each tool answers

Where it runs Enforces a $ cap per customer? What happens at the cap Needs
LiteLLM proxy A proxy between your app and providers Yes: budgets per customer/end-user, key, user and team Proxy rejects the request (429 budget_exceeded), or reroutes to a cheaper model with per-key budget fallbacks Running the proxy and its database
Helicone A gateway in the request path (hosted or self-hosted) Yes: cost-based rate limit per user Gateway returns 429 Routing requests through Helicone, plus headers
Langfuse Observability (SDK/OTel traces, async) No: tracks cost per user and alerts You get an alert (Slack, webhook…) Langfuse SDK/integration
In-process (e.g. llmbrake) Inside your app code, around the client call Yes: monthly budget per customer, plus downgrade Throws before calling the provider A store you own (memory, Redis, DB)

LiteLLM proxy

LiteLLM's proxy has first-class budgets. You create customers (end users) with a max_budget and a budget_duration, or attach a shared budget created via /budget/new (which can also carry rpm/tpm limits). You pass the customer ID on each request, and the proxy tracks spend and rejects requests over budget. Keys, internal users and teams can have budgets too. Docs: https://docs.litellm.ai/docs/proxy/customers and https://docs.litellm.ai/docs/proxy/users

LiteLLM also has budget fallbacks (https://docs.litellm.ai/docs/proxy/budget_fallbacks): per-model caps on a virtual key (model_max_budget) with a chain of cheaper models (budget_fallbacks) to reroute to when a cap is hit. That's configured per key, not per customer, so check whether it maps onto your plans.

Things to know:

  • Budgets and spend live in the proxy's database. Customer budgets are global per deployment: one budget per customer ID, shared across all keys and teams.
  • LiteLLM caches budget objects for up to 60 seconds, so edits take up to a minute to apply.
  • It's a whole gateway: routing, fallbacks, virtual keys, logging. That's a lot of value if you want it, and one more service to run if you don't.

Choose it if: you already run (or want) a central LLM gateway. If you're on LiteLLM's proxy today, use its customer budgets. You don't need another library.

Helicone

Helicone is an observability platform and gateway. Its custom rate limits can be cost-based and per user: send Helicone-RateLimit-Policy: 500;w=3600;u=cents;s=user plus Helicone-User-Id, and that user can spend 500 cents per hour before Helicone starts returning 429. The minimum window is 60 seconds. You also get cost per user and per custom property in the dashboard. Docs: https://docs.helicone.ai/features/advanced-usage/custom-rate-limits

Things to know:

  • Requests go through Helicone's gateway (hosted, or self-hosted).
  • The limit is a rolling-window rate limit. That's good for abuse protection; it maps less directly to "this customer's plan includes $20 per calendar month" with a downgrade step at 80%.

Choose it if: you want observability and per-user cost limits in one product and are fine routing through a gateway.

Langfuse

Langfuse traces your LLM calls and computes token usage and cost, broken down by user, session, feature and model. You can alert on cost metrics, filtered by user, model or tag, via Slack, webhooks or GitHub Actions (Langfuse Cloud plans include 2 to 100 alerts), and query everything via the Metrics API. If you route through OpenRouter or LiteLLM, Langfuse can record the cost they report directly. Docs: https://langfuse.com/docs/observability/features/token-and-cost-tracking

Things to know:

Choose it if: you need visibility (which customers and features cost what) and evaluations. Pair it with an enforcement layer. They don't conflict.

In-process (llmbrake)

The fourth option skips the proxy. A small wrapper in your app checks the customer's spend before each call, picks a cheaper model near the cap or refuses at the cap, and records the cost from the response's token usage into a store you control.

const guard = createGuard({
  budgetUsd: (ctx) => (ctx.plan === "pro" ? 20 : 2),
  downgradeAt: 0.8,
  downgradeMap: { "gpt-5.5": "gpt-5.4-mini" },
  store: redisStore, // your Redis/DB
});
const create = guard.wrap(chat.create.bind(chat));
await create({ model: "gpt-5.5", messages }, { customerId: user.id, plan: user.plan });

What you get: no extra hop or service, your own provider keys, budgets computed from your own plan data, a downgrade step tied to each customer's budget, a typed error to drive an upgrade prompt, and metadata only (prompts and completions are never stored). That's llmbrake, MIT, on npm.

Things to know (honestly):

  • It's v0.1.0. Chat-completions-style usage only: images, audio, embeddings and tool fees aren't priced.
  • You maintain prices. It ships a dated price table you must verify. A gateway that reads provider-reported cost (OpenRouter returns usage.cost) doesn't have this problem.
  • Concurrent overshoot. Spend is checked before a call and recorded after it, so parallel calls can overshoot the cap by their own cost. LiteLLM narrows this window by reserving estimated cost before each request.
  • Dashboard: coming soon. The SDK gives you events (onUsage) and a status() call to feed your own logs. The hosted dashboard (per-customer cost, alerts, margin) is coming soon, with early access for founding members on the waitlist.
  • Every service needs it. If you call models from several services or languages, each one needs the wrapper (TypeScript and Python exist today). A central gateway enforces in one place.

Choose it if: you don't want a proxy in your request path, you want budgets tied to your own plans with a downgrade step, and you're fine owning a small store.

Combining them

These aren't exclusive:

  • Langfuse + llmbrake: Langfuse for visibility and evals, llmbrake to enforce. Forward llmbrake's onUsage events as trace metadata if you want them in one place.
  • LiteLLM or Helicone alone: if you already route everything through a gateway, its budgets are the simpler choice. Adding an in-process layer only makes sense if you need plan-aware downgrades in app code.
  • OpenRouter + llmbrake: wrap the OpenAI-compatible client and add OpenRouter model IDs to the price table.

A quick decision guide

  1. Already running a gateway (LiteLLM, Helicone)? → Use its per-customer budgets.
  2. Only need to see cost per customer? → Langfuse (or Helicone) dashboards and alerts.
  3. Need to enforce per-customer dollar caps, without a proxy, with plan-based budgets and downgrades? → In-process: llmbrake, or ~150 lines of your own using the same check → call → charge pattern.

If I've got something wrong about any of these tools, tell me and I'll fix it. Corrections are welcome: https://github.com/llmbrake/llmbrake/issues


Try the live demo (a browser simulation, no API keys needed), read the README, or see how LLMBrake compares with LiteLLM, Helicone and Langfuse.

More from the blog