Skip to content
← All posts
Cost control 6 min read

Keeping AI Spend Predictable With Wallets and Per-Tenant Budgets

AI features fail commercially long before they fail technically, usually because nobody metered the spend by tenant.

A normal SaaS feature costs roughly the same to serve every customer. An AI feature does not. One tenant asks three questions a day; another wires your chat endpoint into a batch job and fires forty thousand requests overnight. Your infrastructure bill for that tenant just went from two dollars to eighty, and your flat monthly subscription price didn't move at all.

This is the part of shipping AI features that catches technical teams off guard, because it isn't a bug. The model did exactly what it was asked to do, correctly, for every single call. The problem is that nobody put a ceiling on how many calls a tenant could make before someone noticed the margin disappearing.

We've built subscription billing, usage metering, entitlement gating, and AI spend wallets with auto-recharge across our own products and client platforms. The pattern that holds up in production is simple to state and easy to skip under deadline pressure: meter every call, attach a budget to every tenant, and make the system refuse gracefully when the budget runs out. Everything below is how we implement that.

The cost problem AI features create that ordinary SaaS costs don't

Compute for a web request is bounded. A database query takes milliseconds regardless of who's asking. An LLM call is different on two axes at once: the price per call varies with input and output length, and the number of calls a feature triggers is often decided by the model itself, not by your code. An agent that loops through a tool three times because the first two results looked ambiguous just tripled its own cost, and it did so without asking anyone's permission.

Multiply that by tenants and the variance compounds. A construction firm running vision-model takeoff against a fifty-page plan set spends very differently than one running the same feature against a four-page addendum. If your pricing model is a flat monthly fee, you are underwriting that variance out of your own margin every month until someone builds visibility into it.

Wallets, not invoices: meter usage before you bill for it

The fix that has worked for us is a wallet model rather than a pure invoice model. Each tenant carries a balance, denominated in cents or credits, that gets debited at the moment of consumption, not at the end of the billing cycle. When the balance hits zero, the AI feature is disabled or degrades to a cheaper path until the tenant recharges, either manually or automatically.

This matters for a reason that has nothing to do with billing software: it moves cost enforcement from finance, who finds out thirty days late, to the request path, where it can actually stop the spend. A wallet check is a database read that happens before the model call, not a report someone reads after the invoice has already gone out.

A schema for metering that survives production

The metering table needs to record enough to answer two questions later: what did this cost, and what was it for. We keep a ledger row per call and a running balance per tenant, updated in the same transaction so the two never drift apart.

create table ai_usage_ledger (
  id            bigserial primary key,
  tenant_id     uuid not null,
  feature       text not null,        -- 'takeoff', 'chat', 'invoice_ocr'
  model         text not null,
  input_tokens  int not null,
  output_tokens int not null,
  cost_cents    int not null,
  created_at    timestamptz not null default now()
);

create table ai_wallet (
  tenant_id       uuid primary key,
  balance_cents   int not null,
  auto_recharge   boolean not null default false,
  recharge_amount int,
  low_balance_at  timestamptz
);

The feature column earns its keep the first time someone asks why a tenant's spend spiked. Without it you're guessing between chat, OCR, and a background retrieval job that got triggered by a cron. We use the same ledger structure whether the underlying pipeline is confidence-scored extraction or a free-form chat endpoint, because the billing question is identical even though the review question is not.

Setting the budget: hard caps, soft caps, and auto-recharge

A single ceiling isn't enough, because a tenant can run out of budget two different ways: gradually, through normal use, or suddenly, through a runaway agent loop or a scripted client hammering your API. Each needs a different response. Our rule of thumb is three thresholds per tenant, not one.

  • Soft cap at 80% of balance — fire a webhook or in-app notice so the tenant (or their admin) sees it coming, before the feature stops working.
  • Hard cap at 0% of balance — disable the paid AI path immediately and fall back to a non-AI default where one exists, rather than a hard error.
  • Per-request ceiling — a maximum token or dollar cost for any single call, independent of the wallet balance, that catches a malformed prompt or an agent stuck in a tool loop before it drains a week of budget in one request.
  • Auto-recharge threshold — if enabled, trigger a recharge at the soft cap, not at zero, so there's no gap where the feature is down while a payment processes.

The per-request ceiling is the one teams skip, and it's the one that actually prevents the worst incidents. A tenant slowly spending through their monthly allotment is a pricing conversation. A single request that spends three days of budget because an agent kept re-selecting the wrong tool is an incident, and it needs a circuit breaker that doesn't care what the wallet balance says.

Where this breaks down

Wallets add real friction, and it's worth naming where they cost more than they're worth. If your AI feature runs at a fixed, low volume per tenant — say, a single classification call per invoice, capped by a workflow that only fires once per document — a flat monthly allotment with a simple alert at 90% usage is enough. Building a full ledger and auto-recharge flow for a feature that costs eleven cents per tenant per month is effort spent on the wrong problem.

Enterprise buyers also push back on usage-based pricing more than they push back on flat pricing, because it makes their own internal budgeting harder. In those deals we've kept the wallet mechanism for internal cost tracking and margin visibility, but exposed a flat price to the customer with a generous, quietly-enforced ceiling behind it. The metering still matters; it just doesn't need to be the pricing model the customer sees.

And before any of this, the cheapest cost control is not calling the model at all. A good number of features that get built as an LLM call are better solved as a query against structured data, and no wallet design fixes a feature that shouldn't have been calling the model in the first place.

The operational habit that makes it work

The schema and the thresholds are the easy part. The habit that actually keeps spend predictable is looking at the ledger weekly, not just when a tenant complains. We pull cost-per-tenant-per-feature and watch for the shape of the curve, not just the total. A tenant whose spend doubled because they onboarded more users is healthy growth. A tenant whose spend doubled with no change in seat count is either a new workflow worth pricing for, or a bug worth fixing before it becomes a pattern across your whole tenant base.

A wallet check is a database read that happens before the model call, not a report someone reads after the invoice has already gone out.

None of this needs to ship in version one. It needs to ship before the first tenant finds a way to use your AI feature harder than you modeled, which happens sooner than most teams expect. If you're scoping an AI feature now and want the metering and entitlement layer built in from the start rather than retrofitted after a bad invoice, see what we build or start a project with us.

Frequently asked

What's the difference between rate limiting and a spend wallet for AI features?

Rate limiting caps the number of requests in a window. A spend wallet caps dollars, which matters because AI requests vary wildly in cost depending on input length, output length, and model choice. A tenant can stay under a rate limit and still blow through a cost budget.

Should AI usage be metered per user or per tenant?

Per tenant, with a per-user breakdown inside the ledger for visibility. Budgets, entitlements, and billing almost always attach to the paying account, not the individual seat, so the wallet balance and enforcement should live at the tenant level even though you still log which user triggered each call.

How do you handle a tenant hitting their AI budget mid-task?

Fail to a degraded but functional state rather than a hard error where possible: disable the AI enhancement and fall back to the manual or non-AI version of the feature. A per-request ceiling and a soft-cap notice before zero balance prevent most mid-task failures from happening at all.

Is usage-based AI pricing better than flat-rate pricing?

Neither is universally better. Usage-based pricing protects your margin against variance but adds buyer friction, especially with enterprise procurement. Many teams meter usage internally for cost visibility and enforcement, while presenting customers a flat price with a quiet ceiling behind it.

What should trigger an alert versus an automatic shutoff on AI spend?

Gradual budget consumption near a threshold should alert a human, since it's usually a pricing or growth signal, not an incident. A single request exceeding a fixed cost ceiling should trigger an automatic shutoff, since that pattern usually indicates a bug, a loop, or misuse that needs to stop immediately.