Usage-based billing is fashionable because it aligns revenue with value delivered. It's operationally brutal because every mistake — double metering, delayed reporting, missed overage — shows up on a customer invoice with no chance to hide it.
# The four moving parts
Meter: the primary usage counter (API calls, GB stored, seats-active, tokens processed). Must be idempotent, real-time, and auditable.
Aggregation: how meter events roll up to billable units. Sum? Peak? Average? Distinct-count? Different answers, different revenue.
Rating: the pricing function applied to aggregated usage. Tiered? Volume? Per-unit? Committed-use discount?
Invoicing: how rated usage becomes a document the customer pays.
Each layer has failure modes.
# Metering: idempotency is non-negotiable
Every meter event needs an idempotency key. If the same API call gets counted twice, you overcharge. If it gets missed, you undercharge. Both are unrecoverable trust breakers.
await meter.record({
customer_id: "cus_123",
event: "api_call",
timestamp: 1710000000,
idempotency_key: `req_${requestId}`, // must be unique per business event
quantity: 1,
});
Store idempotency keys for 90 days minimum. Retry-safe from any client failure.
# Aggregation: pick the right shape
- Sum: API calls, tokens, bytes. Default.
- Peak: concurrent users, active workers. Charge for the max resource footprint.
- Distinct-count: monthly active users. Only unique IDs count.
- Time-weighted: GB-hours of storage. Bytes × time.
Getting this wrong changes revenue by 30%+. Talk to finance before choosing.
# The bill-shock problem
The single biggest cause of usage-based churn is invoices customers didn't expect. Prevention:
- Real-time usage visibility. Customer dashboard shows current-period usage vs. budget, updated hourly.
- Alerts at thresholds. 50%, 80%, 100% of expected spend. Email + in-product.
- Hard caps optional. Enterprise customers want caps; consumers usually don't. Offer both.
- Predicted final bill. "At this rate, this month will be $847." Not scary if it's expected.
# Overage design
Two models:
Included + overage: Plan includes 10K API calls, then $0.001 each. Predictable base, upside on heavy users.
Pure consumption: No base, meter from zero. Better for infrequent use, worse for revenue predictability.
Most SaaS should ship the first. It gives customers a floor to plan around.
# The credit / debit reconciliation
Usage-based invoices are calculated in arrears. Which means the customer's actual bill is unknown until period-end. This breaks:
- Preauthorized card holds (Stripe allows up to 7 days; usage bills can be 30+)
- Budget forecasts
- Purchase order approval flows
Solution: prepaid credits. Customer buys $500 in credits. Usage draws down. Auto-refill at threshold. This turns usage-based into a prepaid model with all the retention benefits of annual.
# Metering infrastructure
Options in ascending complexity:
- Stripe Meters (2024+) — good for < 10K events/sec, integrates with Stripe billing
- Orb / Metronome / Lago — dedicated usage-billing platforms
- Self-built on Postgres + Redis — flexible, expensive to maintain
Under $10M ARR use Stripe. $10M–$100M use Orb/Metronome. Above that, evaluate self-build with a dedicated team.
# The rev-rec question
Usage-based revenue is recognized as the service is delivered — meter events are the delivery. This is simpler than subscription rev-rec, not harder, but requires:
- Clean event stream to accounting
- Cutoff handling at period boundaries
- Late-arriving events policy (30-day close is standard)
Coordinate with your finance team from day one. Retrofitting rev-rec on usage-based billing after the fact is a nightmare.