Articles
Usage Metering System Design Interview: Deduplication, Late Events, and Billing Corrections
Prepare for usage metering system design interviews with immutable events, deduplication, late-event windows, invoice lineage, and corrections.
A usage metering system design interview sits between distributed systems and money. At-least-once delivery can bill twice; event-time delays can move usage into the wrong month; and a corrected source record may arrive after an invoice is final. A dashboard total is insufficient unless it can explain the charge.
Stripe officially documents unique meter-event identifiers, optional event timestamps, asynchronous aggregation, meter formulas, and cancellation adjustments under product-specific limits. These are concrete examples, not a universal billing contract. The internal ledger, lateness policy, and correction workflow below are editorial design recommendations.
For a closely related drill, use Design A Drive-Style Usage Quota Limiter.
Usage Metering Interview: Quick Answer
Producers emit immutable usage events with globally stable event_id, tenant, meter, quantity, event time, source, dimensions, and schema version. The intake ledger durably accepts or rejects each event once. A normalized stream assigns the price and account identity versions. Aggregators maintain period buckets plus a watermark and can rebuild them from the ledger.
Keep billing periods open through a declared lateness window. Finalization snapshots event ranges, aggregate hash, tariff version, currency/rounding rules, and invoice line lineage. A later correction is an append-only reversal or delta feeding a credit/debit workflow; never rewrite the finalized evidence invisibly.
The Core Contract
Usage metering is an auditable event-to-invoice pipeline. The bill must retain lineage to accepted events and tariff versions so duplicates, lateness, and corrections are explainable.
| Record | Immutable identity | May change? | Downstream role |
|---|---|---|---|
| raw usage event | producer event ID | no | evidence of observed usage |
| normalization result | event + ruleset version | new version only | account/meter mapping |
| period aggregate | tenant, meter, period, generation | rebuild generation | invoice input |
| invoice snapshot | invoice and line ID | finalized no | customer charge |
| correction | original event/invoice reference | no | credit, debit, or future adjustment |
This lineage lets support move from a line item to the exact accepted inputs and transformations.
Define the Billable Event at the Producer Boundary
Agree on a unit: API call, token, byte-hour, active seat, or job-minute. Specify whether zero and negative quantities are valid, required dimensions, and how a producer derives a stable ID. A random ID created on every retry defeats deduplication; derive it from the logical operation or persist it before sending.
Authenticate producers and authorize tenant/meter pairs. Reject malformed or impossible events to a visible quarantine with reason. Acknowledgment means the raw event is durable, not that the future invoice already includes it. Publish intake lag and rejection counts so “accepted” and “billed” are not conflated.
Deduplicate Without Pretending Storage Is Infinite
A unique constraint on producer and event ID is the clearest first line. If the same ID arrives with identical content, return the original acceptance. If content differs, quarantine the conflict because silently choosing one hides a producer defect. Keep the durable event ID at least as long as the maximum replay and correction horizon required by the business.
Bloom filters can reduce duplicate lookups but false positives make them unsafe as the only billing decision. Use them as an optimization in front of authoritative storage. Pre-aggregation reduces volume but shifts proof to signed batch IDs, interval boundaries, and replacement semantics.
Use Event Time, Watermarks, and Open Periods
Record event time and server receive time. Event time assigns the economic occurrence, while receive time reveals delay and prevents arbitrary backdating. Define allowed lateness by source and product. Aggregators expose a watermark through which all normally expected input is processed; they do not claim no older event can ever arrive.
An open period may be recomputed as late events arrive. At close, wait the policy window, reconcile producer counters and rejected events, then freeze a generation. Extremely late events enter an exception path or next-period correction under the customer contract. State this choice rather than quietly dropping them.
Make Corrections Visible After Finalization
Before finalization, cancel or replace the erroneous event and rebuild the aggregate. After finalization, preserve the invoice and issue a credit, debit, or adjustment linked to the original line. Approval limits and customer communication depend on amount and jurisdiction, so keep them as policy inputs rather than hard-coded interview assumptions.
Reconciliation compares raw accepted quantity, normalized quantity, aggregate quantity, and invoice quantity by tenant/meter/period. Track duplicates, conflicting IDs, late-event value, unpriced events, aggregate drift, correction rate, and oldest unprocessed event. A full rebuild should reproduce the same invoice snapshot hash.
Work Through a Failure Trace
Events E1=100 and E2=50 arrive for August; E2 retries identically and changes the total zero additional times. E3=20 occurred in August but arrives before the close watermark and raises the open total to 170. After finalization, E1 is proven overstated by 10. A linked correction creates the applicable credit path while preserving the original 170 snapshot.
Usage Metering check: What uniquely identifies one billable usage event? Walk the trace once in event-time order, once with retries and reordering, and once after rebuilding projections from durable records. State the expected invariant after every step. If the outcome depends on message arrival order when the contract says it should not, the design is missing an identity, version, or transaction boundary. If the design intentionally permits a temporary difference, give it a watermark, maximum age, and repair owner.
Usage Metering check: Which timestamp assigns usage to a billing period? This trace is an interview model, not a measured production benchmark. Add a skew test concentrated on one tenant or key, a two-times-peak capacity test, and a fault injection at the acknowledgment boundary. Preserve input versions and random seeds so a failed run can be reduced and replayed.
Turn the Requirements into Verification
Write these five questions beside the diagram: What uniquely identifies one billable usage event? Which timestamp assigns usage to a billing period? How long can late events revise an open period? How is a finalized invoice corrected? Can every charge be traced back to source events and price rules? Each question must point to a record, transition, test, and observable signal. If one can be answered only with 'the service handles it,' the contract is still incomplete.
Usage Metering check: How long can late events revise an open period? Build a deterministic fixture with five to ten timestamped inputs. Include an identical retry, a conflicting reuse of an ID, a late or stale input, a worker failure after durable work but before acknowledgment, and a rebuild of the serving projection. Expected results must be written independently of the implementation. Verify the authoritative state, the serving state through a named watermark, and every emitted correction or rejection reason.
Usage Metering check: How is a finalized invoice corrected? Then add property checks. Applied logical IDs remain unique; versions never move backward; reserved or consumed value obeys the topic's invariant; a rebuild through the same input boundary produces the same digest; and an unauthorized reader cannot cross its scope. Generate reordered deliveries around the boundary instead of testing only the happy sequence. A passing fixture proves these declared cases, not production throughput or every network failure.
Usage Metering check: Can every charge be traced back to source events and price rules? For fault testing, stop a worker immediately before and after its commit, duplicate queue delivery, delay one partition, and make the read projection unavailable. The runbook should say whether intake pauses, work accumulates durably, readers serve a last-known-good generation, or the request fails closed. Record the recovery point and compare the rebuilt digest before switching traffic. This is concrete evidence that the recovery story matches the write contract.
Capacity, Operations, and Recovery
Usage Metering check: What uniquely identifies one billable usage event? Estimate the durable write rate, average and peak payload, partition skew, retention volume, read or query shape, and acceptable lag. Convert those assumptions into partitions, worker concurrency, storage tiers, and backpressure. Numbers are sizing inputs, not universal facts. Say which limit fails first and what the user sees when it does.
Usage Metering check: Which timestamp assigns usage to a billing period? Operate from contract metrics: accepted-versus-applied counts, duplicate/conflict rate, oldest pending work, authoritative-versus-serving divergence, retry exhaustion, and p95/p99 latency. Alert on sustained error-budget consumption and correctness gaps rather than raw traffic. Keep a runbook that can pause intake or rollout, drain work, rebuild a named projection through watermark W, verify a checksum, and switch readers to the new generation.
Usage Metering check: How long can late events revise an open period? Use least privilege between producers, workers, control plane, data plane, and investigators. Encrypt transit and storage, rotate credentials, audit high-risk actions, and avoid placing secrets or unnecessary personal data in operational logs. Security controls support the data contract; they do not replace idempotency or verification.
Misleading Answers and Better Follow-Ups
Usage Metering check: How is a finalized invoice corrected? A weak answer names Kafka, Redis, and a database before defining truth. Another says “exactly once” without identifying the idempotency key, persistence boundary, or replay behavior. A third adds a cache but cannot explain invalidation or rebuild. Replace each slogan with one invariant, one linearization point, and one counterexample.
Usage Metering check: Can every charge be traced back to source events and price rules? Ask the interviewer to change a requirement: permit temporary staleness, add multiple regions, require a correction after finalization, or remove a dependency. Explain which state transition, key, and monitor changes. That is more useful than redrawing the same boxes at a larger scale.
Usage Metering check: What uniquely identifies one billable usage event? Separate three evidence classes in the answer. Official documentation supports the cited product or protocol behavior. The proposed architecture, thresholds, and sequencing are inference from the stated requirements. This prevents a sensible design choice from being presented as an external fact.
A 45-Minute Interview Plan
Spend the first five minutes clarifying actors, scale, correctness, retention, and failure expectations. Use the next eight to define the authoritative records, IDs, versions, and invariants. Draw the write path and its acknowledgment boundary for ten minutes, then the read or serving path for five.
Use ten minutes for the title-specific failure trace, including one retry, one stale or late event, and one recovery. Reserve the final seven minutes for sizing, skew, access control, monitors, and trade-offs. Keep a short list of assumptions visible. When the interviewer changes one, update the affected contract before changing components.
End with the source of truth, the permitted temporary inconsistency, and the repair procedure. A compact design that can be replayed and verified is stronger than a large architecture with undefined states.
Final Takeaway
For a usage metering system design interview, lead with this thesis: Usage metering is an auditable event-to-invoice pipeline. The bill must retain lineage to accepted events and tariff versions so duplicates, lateness, and corrections are explainable. Define the evidence boundary, run a concrete race or failure trace, and show how the system detects and repairs divergence.
Sources and Further Reading
- Stripe record-usage API guide
- Stripe meter configuration
- Stripe Meter Event object
- Stripe Meter Event Adjustment
Official sources support only the cited mechanism. Architecture recommendations, capacity figures, and interview sequencing are editorial inference.