All posts

What you'll build alongside Metronome

Blog·Ryan EchternachtRyan Echternacht·Oct 13, 2026
Schematic Vs. Metronome
Teams arrive at Metronome from one of two places. Some are moving to usage pricing and want the billing side right the first time. The rest already did it once, in-house or on a tool that wasn't built for it, and they're still paying for that. A usage table nobody trusts. A month-end job that double-counts retries. An invoice dispute that costs days to settle.
Metronome is built for both. It takes events at scale, deduplicates them, tolerates late and backdated usage, and turns the result into an invoice that holds up. It handles the contracts those customers sign too, with commits, per-customer rates, rollover, and price changes scheduled for next quarter. Since January it's part of Stripe. If your worry is metering a lot of usage correctly and billing it against enterprise contracts, that's what Metronome is for.
Until recently, metering was the whole job. A customer going over their limit didn't cost you anything, so you settled it on the invoice. Features powered by AI models changed that. Every run costs real money, and agents run them with nobody watching. Counting usage after the fact is now half the job. The other half happens before the run, when you have to decide whether this customer can start it with what they have left. Metronome stops at the meter, leaving everything else to you.

Where Metronome stops

Metronome doesn't have an endpoint that answers "is this allowed?" Its prepaid credits guide recommends that "a customer's entitlement state is managed within your system and database." The pattern it describes is a flag per customer in your database, flipped when a balance webhook arrives.
The signals behind that flag run on billing time. Balance alerts fire within minutes, not milliseconds. Webhooks arrive with minimal payloads, so you call the API back for the details. There are balance endpoints, but they're rate limited at the account level, which rules them out as a check in front of every action. Even zero-overage pricing, which guarantees a customer is never billed past their commit, "does not stop usage from being submitted."
A billing system has to be right when the invoice goes out. Your product has to be right before the next action runs. Those are different guarantees, and only one of them ships with Metronome.
So you build the other half. Some of it is code. The rest is keeping up with what customers ask for, and both keep growing.

What engineering builds

It starts with webhooks. Every check your product makes reads local state, and that state is assembled from Metronome's webhooks and API reads. So you write the receiver, and it has to handle signature verification, retries, duplicates, and events arriving out of order. You keep a store of each customer's balance and access. You run a job that reconciles that store against Metronome, and you decide what the product does when the store is stale or the job falls behind.
Then the check itself, which sits in front of every billable action. The first version is a lookup against that store.
typescript
if (balance(customer.id) < cost) return outOfCredits()
await run(action)
recordUsage(customer.id, cost)
That holds up as long as an action has a fixed price and one caller at a time. Agents break both.
You don't know the cost of an inferenace-based call until it finishes, so there's nothing to compare the balance against. So you estimate, hold that many credits, start the agent, and settle the actual amount when it's done.
typescript
const hold = await ledger.reserve(customer.id, estimateCredits(job))
if (!hold) return outOfCredits()

try {
  const result = await runAgent(job)
  await ledger.settle(hold, result.creditsUsed)
} catch (err) {
  await ledger.release(hold)
  throw err
}
typescript
ledger
is code you write. Now two agents for the same customer start at the same time. Both see 100 credits remaining, both pass, and they spend 150 between them. So you need holds that can't be taken twice, which means a shared ledger that every agent run checks with before it starts. You need those holds to expire, because workers die mid-run and their credits shouldn't stay locked. You need settlement to handle a run that cost more than you held. And you need an answer for what the check does when the ledger itself is down.
Credits aren't the only thing you check. Most products end up with features that are on or off by plan, usage limits that reset daily or monthly, seat counts that should block the next invite, and credits on top. Each one has its own state and its own check. Metronome bills the seats you report. Stopping the eleventh seat on a ten-seat contract is your code.
Balances also change for reasons that have nothing to do with usage. Customers buy more credits, auto top-ups fire, grants arrive, unused credits roll over or expire at the end of the period, and support issues refunds. Metronome's ledger records all of it. Your local copy has to apply each change before the next check runs, or a customer who just paid gets told they're out of credits. Some changes arrive as side effects. When an auto-recharge payment fails, Metronome turns auto-recharge off, and your app needs to hear about it before the balance hits zero.
Per-user caps come next, usually because an enterprise customer asks. Metronome can give each seat its own credit allocation, but overages are billed at the contract level, so nothing stops one user from spending the team's month. You build per-user counters, per-user resets, and a check that respects the user's cap and the company's balance at the same time.
And then pricing changes. A new credit rate for a more expensive model, a new plan, a usage limit that turns into a credit burn. Each one is a new code path, a migration of your local state, and new tests. In practice it's a project every time.

What customers will ask for

Customers won't wait for a project every time. Finding the right value metric takes iteration, and sales-led companies iterate one deal at a time. One customer wants a commit with overage, another wants a flat credit pool, a third wants seats with credits attached. Metronome can bill all three. Whether your product enforces all three depends on whether someone wrote the code for that shape. When every experiment waits on engineering, you run fewer experiments, and you learn what customers value more slowly.
Plan changes are where billing and access drift apart. A contract edit in Metronome changes the invoice. Access has to change at the same moment. An upgrade mid-period should raise the limit now, a downgrade at renewal should lower it then, and legacy customers should keep their old limits while new customers get the new plan. Moving a cohort to new pricing means changing their contracts and their access together. A customer who goes past due needs a decision too. Cut them off, degrade them, or give a big account some grace.
Per-user caps look different from this side. An enterprise buyer wants to split their commit across teams, roles, and agents, and their admins want to set and change those caps themselves. A cap that takes a support ticket to change is a ticket queue, not a feature.
Someone also has to decide what happens at the limit, per customer. A hard stop for the free tier, a soft limit with overage for mid-market, auto top-up for self-serve, a negative balance and a phone call for the largest account. Customers need to see their balance in the product before they hit the limit, not on the invoice after. Each of those policies lands back on the technical side as another branch in the check.

Why Schematic

Schematic is the half past the meter, built as one system with the meter. Usage events go to Schematic, the credit ledger lives in Schematic, and the check in front of every action reads from state that Schematic streams into your app. Billing stays on Stripe, where your subscriptions already are, and Schematic keeps Stripe in sync.
That changes what's left to build. Schematic streams entitlement state into your app over a persistent connection, so a check evaluates locally against current state instead of waiting on a webhook or an API call. There's no receiver to write and no balance to reconstruct. The check is one call, and it covers on/off features, usage limits, seats, and credits. In React it's a hook, and a feature that burns credits looks like any other feature, with the balance already on the result.
typescript
const MyComponent = () => {
  const { creditSettled, value: isFeatureEnabled } =
    useSchematicEntitlement("my-flag-key");

  if (!isFeatureEnabled) {
    return <OutOfCredits />;
  }

  return <Feature creditsRemaining={creditSettled} />;
};
Tracking the event burns credits at the rate set on the plan, and the next check sees the new balance. For agents whose cost isn't known up front, the same check can hold credits and the track settles them, so two agents can't overspend one balance and a worker that dies mid-run gives its credits back on a timer. Purchases, top-ups, refunds, rollovers, and expirations land in the ledger directly too. Per-user and per-company caps are in beta.
Going over the limit is the moment customers notice, and it's where most of the build-it-yourself branches live. With Schematic the policy is attached to the customer's plan, so the check returns the outcome along with the answer. A soft limit allows the run and sends the overage to Stripe for the invoice. A hard limit denies it, and the response carries usage, allocation, and balance, so the paywall shows the real number instead of a guess. Auto top-up buys the next bundle when the balance drops below a threshold, and the next check sees the new balance. Warning and limit-reached events fire as webhooks, and the balance components in your product update as usage happens, so a customer sees it coming. Switching one customer from a hard stop to overage is a change to their plan, not a deploy.
The customer side moves out of code too. Plans, custom plans for a single customer, and per-customer overrides are configuration. Publishing a new plan version asks whether to migrate everyone, migrate some, or leave existing customers on their current version. Customers see their balance in the product through drop-in components. None of that is a project.

When Metronome on its own is enough

Not every team needs this. If you bill seats and usage in arrears and never need to stop anyone, Metronome's alerts and invoices cover it. If you're deliberately generous while you learn what customers value, metering everything and enforcing nothing, enforcement can wait. If all you need is one hard cap on one balance, a webhook-driven flag and a nightly reconciliation may be all you ever build.
The build gets heavy when credits are shared, when agents run concurrently, when deals are custom, and when pricing changes every month. That describes most AI products a year after they launch usage pricing.
If you build it yourself, two systems answer the question "how much has this customer used?" Metronome answers it for the invoice. Yours answers it for the product. Every price change, contract edit, refund, and top-up has to land in both, and sooner or later they'll disagree. The build is the part you can estimate. The part you can't is that you're now the one reconciling them, for as long as you sell usage.