BillingArchitecture

Metering AI credits without billing disputes

Jun 14, 2026

Most AI products bolt usage tracking on as an afterthought: a counter column that some background job increments and hopes nobody disputes. It works until the first customer asks "why was I charged for that?" — and you have no answer.

The counter trap

A single credits integer that you SET from a value computed in application code has three failure modes:

  1. Concurrent generations race and overwrite each other.
  2. A crash mid-charge leaves the balance and the work out of sync.
  3. There is no history, so a dispute is your word against the customer's.

Money and credits are ledgered, never mutated blindly.

A double-entry ledger

Every movement is an append-only credit_transaction row. The cached balance is only ever changed by a guarded statement:

UPDATE "user" SET credits = credits - $1
WHERE id = $2 AND credits >= $1
RETURNING credits;

If the row comes back, the charge succeeded atomically. If it doesn't, the user was out of credits and nothing happened — no partial state to reconcile.

What the customer sees

  • Every generation, with the model and the exact tokens it consumed.
  • A running balance they can audit line by line.
  • Top-ups and monthly grants as their own entries.

When the next "why was I charged?" arrives, you send a link to the ledger and the conversation is over. See the pricing page for how credits map to plans.


Metering is not glamorous, but it is the difference between a product people trust with their card and one they don't.