Why an account level cap is the wrong tool
OpenAI and the other providers let you set a monthly usage limit on your whole organization. When you hit it, calls start failing. That is a circuit breaker for your entire product, not a scalpel.
Think about what actually happens when you trip it. Every user, including all your happy paying ones, gets a broken feature at the same moment, because one account somewhere ran hot. You took the whole product down to contain a single outlier.
The provider cannot help you here, because it has no idea who your users are. It sees one API key and one total. The knowledge of which customer generated which cost lives in your app, so the cap has to live there too.
The flat subscription problem, in cap form
This all traces back to the same mismatch behind most AI margin pain. Your revenue per user is fixed by the plan price, while your cost per user moves with how much they use.
On a flat plan, a heavy user can quietly cost you more than they pay, and nothing flags it until you go looking. A per user cap is the ceiling that turns that unbounded downside into a number you chose on purpose. It is the same idea as setting spending caps per user, framed around the thing that makes it necessary. The deeper structural version is in why power users hurt your AI margins.
A basic per user cap by hand
The logic is simple. Keep a running total of cost per user id, reset it each month, and check it before every call.
// per user monthly cap, checked before each call
function capFor(plan) {
return { free: 1, pro: 20, business: 100 }[plan] ?? 1 // dollars
}
async function guardedChat(userId, plan, params) {
const spent = await getMonthlySpend(userId) // from your db or cache
if (spent >= capFor(plan)) {
throw new Error('monthly cap reached') // block (see the downgrade option below)
}
const res = await openai.chat.completions.create(params)
const cost = costOf(res.usage, params.model)
await addSpend(userId, cost) // persist so the next call sees it
return res
}That is the whole shape of it. The check is trivial. The parts that bite are keeping getMonthlySpend fast and correct across every serverless instance, and recomputing cost the same way your provider bills so your numbers do not drift.
When a user hits the cap: block or downgrade
You have two moves the moment someone crosses their limit, and the right one depends on the plan and the stakes.
- Block the call. Strict and clear. You throw, and the user is told they hit their limit. The cost stops dead, but that user now has a broken feature until the reset or an upgrade.
- Downgrade the model. Graceful. You swap from a frontier model to a cheaper one, from
gpt-4otogpt-4o-mini, and keep serving. Cost drops hard and most users never notice the difference.
Blocking protects cost the hardest but risks a bad experience, so it fits abuse cases and the very bottom of your pricing. Downgrading protects the experience while still cutting spend, which is why it is usually the better default. The full case for it is in model downgrade on a budget, and choosing which model to drop to is the subject of model routing for LLMs.
Why the manual version gets painful
For one server and a few users, the code above is genuinely fine. It stops being fine at exactly the moment your product starts working.
Spend has to persist somewhere every call can read and write in a few milliseconds, and stay correct when two requests from the same user land at once. You have to wire the check into every feature, reset totals cleanly each month, and decide block or downgrade per plan. None of it is hard on its own, but together it is a small system you now own and maintain forever.
No code caps with Weckr
The alternative is to keep the check but stop building the plumbing. That is what Weckr does. You set the cap per plan in the dashboard, no code, and the SDK enforces it before each call.
import { Weckr } from '@weckr/sdk'
const wk = new Weckr({
apiKey: process.env.WECKR_API_KEY,
plans: { free: 0, pro: 29 },
})
// Weckr checks the user's cap before the call and blocks or downgrades per your
// dashboard setting. You do not track spend yourself.
const response = await wk.chat(openai, {
model: 'gpt-4o-mini',
messages,
userId: user.id,
feature: 'chat',
plan: user.plan,
})You pick block or downgrade per plan in the dashboard, and Weckr keeps the running per user spend, recomputes cost server side, and enforces the limit for you. The setup lives in the docs, you can watch caps run on seeded data at the demo, and it fits into the wider system in the guide to AI cost and margin management.
FAQ
What is a per user spending cap for LLM calls?
It is a limit on how much AI cost a single user can generate in a period, usually a month, enforced before each call. Unlike an account level limit that caps your whole product at once, a per user cap targets the individual who is draining margin while everyone else stays unaffected. When a user crosses their cap you either block the call or downgrade them to a cheaper model.
Why is an account level spending limit not enough?
Because the account limit is a kill switch for your entire product. When you hit it, every user is cut off, not just the one who caused it. It also does nothing to protect your margin on a single heavy user until the total is already blown. A per user cap stops the outlier without touching anyone else.
Should I block the call or downgrade the model when a cap is hit?
Blocking is the strictest and clearest option, but it gives that user a broken experience the moment they cross the line. Downgrading to a cheaper model keeps the feature working at lower cost, so most users never notice. A good rule is to downgrade on cheaper plans for a graceful feel and block only where cost or abuse risk is high.
How do I implement a per user cap myself?
Track cumulative cost per user id in a store you can read quickly, reset it monthly, and check the running total against the plan limit before every call. If the user is over, block or swap the model. The hard part is not the check, it is persisting spend reliably across serverless instances and keeping it correct under load.
Does OpenAI support a spending limit per user?
No. OpenAI offers organization level usage limits, not per user limits, because it has no idea who your individual users are. Per user attribution and per user caps have to live in your own layer, which is exactly what a tool like Weckr adds on top of your existing client.
Keep reading
Put a ceiling on your worst case
A per user cap is the difference between a worst case you chose and one that arrives on an invoice. It is the single most protective thing you can add to an AI product.
Weckr gives you that cap with no tracking code, plus the choice to block or downgrade, and cost and margin per user so you can see who is near the line. Start at the demo.