Blog
/
Guides

Billing System Design: The 5-Layer Architecture Guide

A guide to billing system design for engineering teams building AI products, covering metering, entitlements, real-time enforcement, and build vs. buy.

Sara NelissenSara Nelissen
Written by
Sara Nelissen
Last updated
August 6, 2026
Billing System Design: The 5-Layer Architecture Guide

Table of contents

A voice agent one of our customers built stayed on a call forty minutes past when it should have ended, billing per minute the entire time. The invoice arrived accurately to the second.

Nobody in the review could explain why the system had no way to end the call on its own. That question sat with me longer than the incident did, and it still shapes how I think about billing system design whenever we scope new entitlement work.

What billing system design covers

Many engineers hear "billing system" and picture an invoice generator that aggregates usage, applies a rate, and sends a bill. That is one piece of it, and it gets the most attention because finance cares about it most directly.

Billing system design, done properly, spans usage metering, rating, entitlements enforcement, credit accounting, invoicing, and the customer-facing surfaces built on top of all of it.

  • For a flat-subscription product, most of that surface barely matters. You check a plan tier at login and move on.
  • For a product priced on tokens, credits, or agent actions, every layer has to hold up because mistakes hit your margin the same day.

That's why billing system design means something different depending on who's searching for it. A traditional SaaS company is typically solving for accurate invoicing. An AI company, on the other hand, is typically solving for something closer to access control with a ledger attached.

The five architectural layers of a billing system

Strip a usage-based billing system down to its components, and you get five layers, each with a distinct job.

1. Event ingestion

Every unit of consumption like an API call, a generation job, or a token count becomes an event. This layer has to be idempotent and replay-safe, or duplicate events inflate both your usage numbers and your customers' bills without anyone noticing right away.

2. Rating

This layer converts raw events into cost, applying tiers, package sizes, or per-unit pricing to a stream of events. It answers what the usage costs.

3. Entitlements and enforcement

This layer answers a different question than rating does. Given what a customer has paid for and how much they've already consumed, is this specific request allowed right now? Answering that requires a synchronous check performed when the request arrives.

4. Ledger and credit accounting

Credits, prepaid balances, and auto-recharge all need a financial record. A simple counter falls short. An append-only ledger provides a reconciliation trail that finance can audit and catches balance discrepancies before they turn into chargebacks.

5. Invoicing and payment

This is where Stripe, Zuora, and similar tools operate. They turn rated usage into an actual invoice and collect payment. It's necessary, and it's also the layer most engineering teams reach for first, because it's the most visible one.

The layers that most teams get right on the first attempt are ingestion and invoicing. The layer that gets added after an incident is entitlements and enforcement, because until a customer blows past a limit in production, it doesn't register as its own architectural concern.

Real-time enforcement and deferred billing

Metering tells you what happened. It is inherently retrospective because you cannot meter an event before it occurs.

Enforcement, on the other hand, decides whether to allow a request before execution, so it happens in the request path when the request arrives. This is the difference between a usage tracking system and a usage runtime.

A tracking system can tell you, accurately, that a customer used 12,000 more tokens than their plan allows, after the tokens are already spent. A runtime makes the allow or deny decision at request time, before the cost is incurred.

That runtime layer is exactly what Stigg is built to provide. Stigg is the usage runtime for AI products. Entitlements, credits, usage limits, and spend governance are enforced synchronously in the request path.

Look at how AI products are priced today, and the pattern holds up. 

Anthropic and OpenAI both meter token consumption directly, with account-level limits that cut off requests once a threshold is hit. This is enforcement, running alongside measurement. 

Cursor's usage-based tiers work the same way. Once a plan's included usage is exhausted, the product has to make an allow or deny decision on the next request. A log entry recorded after the threshold was crossed doesn't make that decision on its own.

Any product with a marginal cost per unit of usage eventually needs that same synchronous decision point, whether it's built in-house or bought. For products with real marginal costs, AI tokens, compute minutes, and inference calls, this is a margin-protection system built into the architecture itself.

Design patterns worth following

I've seen most of these adopted only after something already broke in production. None of them are exotic. They're just easy to skip until an incident review makes them non-negotiable.

Idempotent event ingestion

Assign every usage event a unique identifier at the source, and have your ingestion layer reject duplicates as they arrive.

Retries, network blips, and at-least-once delivery guarantees will eventually cause the same event to be sent twice, and downstream deduplication still leaves a window during which inflated numbers are live.

Decouple rating from enforcement

These are different jobs running on different timelines. Coupling them creates a system in which a slow rating calculation blocks a request that only needs a yes-or-no answer. Keep the enforcement check fast and simple, and let rating run on its own schedule.

Cache-backed enforcement for low latency

The first time I saw an entitlement check add real latency to a customer-facing action, it was because someone had wired it to hit a remote service on every request. Stigg solves this with a local cache deployed close to the application, called a Sidecar.

On a cache hit, the entitlement check resolves instantly from local Redis. On a cache miss, the Sidecar fetches from Stigg's Edge API in about 100ms, with a configurable timeout so a slow lookup degrades gracefully instead of blocking the request outright.

Design for real tenancy across the whole org

Enterprise usage isn't flat. Budgets are allocated per user, per team, per product, and per department, often with different limits at each level and different owners approving overages.

A billing system designed around a single "customer" dimension needs a rebuild the first time an enterprise buyer asks for department-level spend caps, and by then that rebuild competes with a live deal for engineering time. 

BYOC where data residency matters

For customers with regulatory or residency requirements, the enforcement layer runs inside their own cloud. That setup is often a procurement requirement in its own right, and it protects against latency spikes from cross-region calls while providing a redundant path if the upstream provider experiences an outage.

Append-only ledgers for auditability

Credits and balances should never be mutated in place. An append-only record of every debit and credit provides finance with a reconciliation trail and evidence that the balance is right.

These patterns matter together. An enforcement layer that's fast but can't handle enterprise tenancy still needs a rebuild further down the road.

Build vs. buy: Where in-house holds up

For a single-product company with a handful of plans and one pricing dimension, an in-house system is typically the right call. A credits table, a decrement function, and a middleware check will hold for years, and there's no reason to add a dependency for a problem that size.

The system begins to strain under specific conditions. Multiple credit types running at once, budget allocations that roll up across an org hierarchy, enforcement that has to run on every request in real time, and an audit trail detailed enough for finance to sign off on.

None of those show up on day one. I've seen them surface when an enterprise customer asks for department-level usage caps, or when a support ticket reveals that a single account has burned through a month's allocation in an afternoon.

Respect why the in-house system got built, because it was almost certainly the right call at the time. The real signal to revisit it is a specific moment, and I've watched teams miss it more than once: when your engineers spend more time maintaining the credit system than building the product it's supposed to be billing for.

Common anti-patterns in billing system design

A few patterns recur in billing systems designed around invoicing, with enforcement added later.

  1. Metering and invoicing are coupled directly. When the same code path both counts usage and generates the bill, there's no place left to insert a real-time check without touching the invoicing logic itself, which makes engineers reluctant to touch it at all.
  2. Batch-only enforcement. A nightly job that flags accounts over their limit catches the problem a day late. For a customer support agent handling live conversations, or a voice agent running continuous sessions, a day is long enough to burn through a quarter's margin on that account.
  3. No audit trail on credit balances. Without an append-only ledger, "why doesn't this balance match" becomes a support escalation instead of a resolved query.
  4. Tenancy hardcoded to one dimension. Systems built assuming "customer" is the only unit of billing tend to need a schema rewrite the first time a team- or department-level limit gets requested.
  5. Rating logic duplicated across services. When two parts of the system independently calculate cost for the same usage, one for the invoice, one for a dashboard, they drift apart over time, and reconciling them turns into a recurring manual task nobody ever fully closes out.

Where to start, if you're evaluating this

The credits engine, entitlements, and metering can each be adopted independently, and many teams start with a single SDK integration before committing to anything larger.

A common first step is wiring up entitlement checks for one high-cost feature, the one most likely to create a margin problem, while everything else stays on your existing setup. If your billing runs on Stripe, it stays in place as well, with entitlements serving as a control layer alongside it.

Expansion from there is driven by a specific trigger, which could be a second product line, a customer request for department-level budgets, or a credit type that requires its own ledger. Each of those is a reason to add another piece, not a reason to have started with the full stack on day one.

Where to go from here

Billing system design for an AI product means treating entitlements and enforcement as their own architectural layer, added early, before an incident forces the issue. Get the five layers right, and reporting, dashboards, and customer-facing controls become much easier to build on top of.

Stigg is the usage runtime for AI products, built for the entitlements and enforcement layer this architecture depends on:

  • Synchronous entitlement checks are enforced in the request path
  • Cache-backed enforcement through a Sidecar, for low, predictable latency under high volume
  • Support for complex tenancy: per-user, per-team, per-product, per-department
  • BYOC deployment, so the enforcement layer runs where your data already lives
  • An auditable, append-only credit ledger
  • Compatible with your existing billing stack, including Stripe and Zuora
  • Modular by design, so you can adopt the credits engine, entitlements, or metering on their own as an added layer

The next runaway session shouldn't have to wait for a dashboard refresh to get caught. See the Stigg docs for the entitlements and Sidecar setup.

FAQs

1. What's the difference between metering and billing enforcement?

The main difference is that metering records what a customer consumed, while enforcement decides whether the next request is allowed, based on what's already been consumed and what the plan permits.

A system can meter perfectly and still let a customer run past a limit if enforcement isn't wired in separately.

2. Do I need a dedicated entitlements layer, or can my billing tool handle access control too?

Yes, in most cases. Billing tools are built to calculate costs and generate invoices, but making an allow-or-deny decision at the time of the request is a separate function that they typically don't cover. 

Entitlements is a distinct layer with its own job: checking, in the moment, what a specific user or agent is allowed to do. Some products bundle both, but the two functions run on different timelines internally.

3. How do you add real-time enforcement without slowing down every request?

The common approach is a cache-backed check running close to the application. Most requests are resolved from local memory, while a fallback path handles occasional cache misses with a short timeout to prevent slow lookups from stalling the request.

4. Is billing system design different for AI products than for traditional SaaS?

Yes, mainly because the pricing dimension changes. Seat-based SaaS checks a plan tier occasionally. AI products priced by tokens, credits, or agent actions incur a real marginal cost for nearly every request, requiring continuous enforcement throughout use.

5. When does it make sense to build a billing system in-house instead of buying one?

For a single product with a handful of plans and one pricing dimension, an in-house system typically holds up fine for years.

It starts to strain once multiple credit types, org-level budget rollups, and per-request enforcement all show up at the same time, which tends to happen well after the original system was built.

Latest news.

One email per month.
From engineers, for engineers.

Thank you! Your submission has been received.
Oops! Something went wrong while submitting the form.