Credits, usage & billing, explained
The problem with LLM usage tracking isn't that it's hard to measure tokens — it's that every provider gives you a different dashboard, and none of them tell you what you actually spent through your application. When you route through a gateway, usage becomes a property of your architecture, not a per-provider afterthought. ModelPlane gives you one surface for usage across all your model groups and providers, so you can answer "what did this feature cost?" without stitching together five vendor consoles.
The multi-dashboard problem
If you've built an AI feature in production, you know the ritual. You have a script, a spreadsheet, or a half-remembered URL for each provider's usage page. OpenAI shows you one number. Anthropic shows you another. DeepSeek shows you a third. And none of them map to the requests your application actually made, because your application doesn't call providers directly — it calls a model group.
The mismatch is the core issue. Provider dashboards are organized by provider account. Your costs are organized by feature, customer, or environment. When you hard-code model="gpt-4o" in your code, you've coupled your application's cost structure to a single vendor's accounting. You can't see which of your features is burning credits, which customer tier is expensive to serve, or whether your fallback routing is quietly sending traffic to a premium model you didn't intend.
This is why the abstraction matters. When request.model is a name you control — a model group like prod-chat — usage tracking becomes something you can actually act on.
One surface for usage across model groups
ModelPlane's billing model is built around a single concept: credits. One credit is equivalent to one US dollar. Every request through the gateway is accounted for in credits, regardless of which provider answered it. The cost formula is straightforward:
cost = (inputTokens × inputUnitPrice + outputTokens × outputUnitPrice) / 1_000_000
The pricing for each model lives in the provider catalog, so the gateway can compute the cost of every request without you configuring per-model rates. This means your usage logs are not just token counts — they're actual spend, normalized across every provider.
The usage_logs table is the heart of this. Each entry records the request's dimensions: which API key made the call, which model group it went through, and which underlying model actually answered. That last point is critical. With fallback routing, the model that answers isn't always the one you asked for. Your logs show you the ground truth.
This gives you three views of your spend that provider dashboards can't:
-
By model group. What does
prod-chatcost this month? What aboutcustomer-supportorinternal-coding? Each group is a line item. - By API key. Which application or service is consuming the most? Private keys per developer, shared keys per environment.
- By model. Even within a group, you can see the split — how much traffic went to the fast tier versus the premium fallback.
The balance gate: what happens before a request runs
ModelPlane's billing is designed to be low-latency and simple. Before a request runs, the gateway checks your credit balance. If you're out of credits, you get a 402 insufficient_credits response — fast, clear, and before any upstream call is made. This is the pre-request balance gate.
This design is a deliberate tradeoff. The gateway doesn't do a strong-consistency reservation of funds before every request. That would add latency to every single call. Instead, it takes a snapshot of your balance, gates the request, and then accounts for the cost after the request completes, asynchronously.
The result is that billing is fast enough to sit on the hot path of every inference call. The tradeoff is that the balance you see can be slightly stale — up to 300 seconds, in some cases, because the balance may be served from a cache. For almost all use cases, this is the right trade. You don't want your LLM gateway to be the slow part of your stack, and you don't want it to reject requests because of a race condition in accounting.
What happens after: async accounting
Once the request completes, the gateway calculates the cost and deducts it from your balance. This is a fire-and-forget operation — it doesn't block the response to your application. The response you get is the model's output; the accounting happens in the background.
This design is simple and fast, but it's worth being honest about the edge cases. The async deduction has no retry mechanism in its current implementation. If the background task fails, or the Worker running it is evicted, the usage row and the deduction could be silently lost. This is a known reliability gap, documented in the project's internal PRD. For most teams, this is acceptable — the cost of a few lost usage rows is far less than the cost of adding strong consistency to every request. But if you're building billing infrastructure on top of usage logs, you should know the data is eventually consistent, not exactly-once.
The system also handles the accounting atomically at the database level. The consume_credits RPC is atomic and allows a brief negative balance, which prevents a burst of concurrent requests from being rejected due to a race between the balance check and the deduction.
Plans and pricing: what you actually pay
ModelPlane's pricing is designed to be transparent. There are three tiers:
- Free: You get $5 in credits on signup. No card required. This is enough to build and test a real feature.
- Basic: $10 per month, which includes $15 in credits. You can top up with additional credits as needed.
- Unlimited: A special plan for high-volume internal use cases, where the credit gate is bypassed entirely.
On top of the plan, there's a flat gateway fee of approximately $0.02 per 1 million tokens. This is the cost of routing — the abstraction, the fallback, the unified billing. It's a rounding error compared to the cost of the tokens themselves, but it's what pays for the gateway to exist.
The key number to understand is the included credit. On the Basic plan, you pay $10 and get $15 in credits. That means the effective cost of the gateway is negative — you're getting more credit than you pay for, and the gateway fee comes out of the included credit. The math works because the gateway fee is so small relative to model costs.
Seeing it in action
Here's what it looks like to point your OpenAI client at ModelPlane and see usage flow into one dashboard:
from openai import OpenAI
client = OpenAI(
base_url="https://modelplane.dev/v1",
api_key="gw-your-gateway-key"
)
# "prod-chat" is a model group, not a provider model id.
# It routes across your configured backends with your chosen strategy.
response = client.chat.completions.create(
model="prod-chat",
messages=[
{"role": "user", "content": "Summarize this week's support tickets."}
]
)
print(response.choices[0].message.content)
That's it. Your application code doesn't know or care which provider answered. It doesn't know whether the request went to a coding-plan quota or a pay-per-token endpoint. It just knows it called prod-chat.
After this request runs, you can query the usage API to see exactly what happened:
curl -H "Authorization: Bearer gw-your-gateway-key" \
https://modelplane.dev/api/usage
The response shows you the request's token count, the cost in credits, the model group, the API key, and the actual model that served it. This is the data you need to answer the questions that matter: "What does this feature cost per user?" "Is my fallback routing sending too much traffic to the expensive model?" "Which customer tier is burning through credits?"
The honest tradeoff: latency vs. accuracy
Every billing system makes a tradeoff between accuracy and latency. ModelPlane's choice is explicit: low latency wins. The pre-request balance check is a snapshot, not a reservation. The post-request deduction is asynchronous, not synchronous. This means your requests are never slowed down by billing logic, and your gateway can handle high concurrency without becoming a bottleneck.
The cost of this choice is that your balance and usage data are eventually consistent. You might see a request in your logs a few seconds after it completes. Your balance might be slightly stale for a few minutes. And in rare failure cases, a usage row might be lost entirely.
For most teams, this is the right trade. If you're building a customer-facing billing system on top of your LLM usage, you should build your own reconciliation layer. But if you want to see what your AI features cost, and you want to catch a runaway model group before it burns through your credits, this is more than sufficient.
Why this beats provider dashboards
The multi-dashboard problem isn't just inconvenient — it's a blind spot. When you can't see usage by model group, you can't see which features are profitable. When you can't see usage by API key, you can't see which developer or service is consuming the most. When you can't see the actual model that answered, you can't tell if your fallback strategy is working as intended.
ModelPlane gives you the dimensions that matter for running an AI product. The abstraction of the model group — the same abstraction that decouples your code from providers — also decouples your accounting from providers. Your costs are organized the same way your architecture is organized.
This is the point. The provider is the wrong unit of integration for your code, and it's the wrong unit of integration for your billing. ModelPlane makes the model group the unit of both. One endpoint, one dashboard, one bill.
The bottom line
LLM usage tracking doesn't have to be a nightmare of spreadsheets and vendor consoles. When you route through a gateway, usage becomes a first-class property of your application. ModelPlane gives you one surface to see it all: credits, spend, and usage across every model group and provider.
The system is fast because it's simple. The balance gate is a snapshot, the deduction is async, and the accounting is eventually consistent. That's the right trade for a gateway that sits on every inference call.
If you're tired of stitching together provider dashboards, point your OpenAI client at ModelPlane and see your usage in one place.
See your usage in one dashboard — start free with $5 in credits, no card required.
This post is part of a series on building production-grade LLM applications with ModelPlane.
The ModelPlane series:
- One endpoint, every model: why we built ModelPlane
- Routing strategies, explained: fallback, load-balance, conditional
- Model groups: the one abstraction that decouples your app from providers
- Bring your own keys, safely
- High availability for LLM apps: a fallback playbook
- Stop paying twice: route your coding-plan quota into production
- Price-aware routing: cut your LLM bill without changing models
- Credits, usage & billing, explained ← you are here
- 1600+ models, one API: the ModelPlane provider catalog
- One gateway, two regions: routing to global and China models
- ModelPlane for teams: orgs, workspaces & shared keys
- Meet the assistant: an AI helper that lives in your gateway dashboard
- Inside the ModelPlane routing engine
- One thinking parameter, every model
- The system prompt belongs at the router, not in your app
Top comments (0)