Product engineering

SaaS usage metering: make corrections explainable

Usage metering needs a rule for what counts, when it belongs and how corrections change it. An executed six-delivery fixture applies four unique entries and attributes 150 units across two open periods. The ledger preserves the original event behind each adjustment.

Executed ledger
6 deliveries, 4 applied entries, 2 duplicates
Period totals
May: 110 units; June: 40 units
Boundary
Assigned open periods; no prices, invoices or provider API tested
Usage tokens enter a ledger while a correction points back to an earlier entry.
Conceptual illustration of preserving original usage and its linked adjustment.

Decide what a customer is paying for

Suppose a SaaS product charges for completed report pages. A worker attempt is not necessarily a completed page: a retry can deliver the same completion twice, and a later review can invalidate some of the reported work. Before connecting an invoice system, the product team needs a defensible answer to one question: which events count toward this customer's usage period?

The executed ledger fixture uses six deliveries for one fictional customer and meter. Two are duplicates. Four unique entries produce 150 units across two periods, whereas simply summing every delivered payload produces 230. These are assigned examples, not observed customer usage or a pricing recommendation.

The contract in this example counts completed pages, attributes them to the period of completion and permits a linked correction while that period remains open. That combination is a product decision. Counting attempted work, attributing late events to their arrival period or handling an already-issued invoice would require different rules.

Keep delivery identity separate from billable meaning

An event needs enough identity to survive retries without confusing two legitimate completions. Here, the deduplication key combines tenant, meter and event ID. Repeating the same key with the same payload is a duplicate delivery. Repeating it with different content is an error requiring investigation, not permission to overwrite the earlier entry.

The fixture accepts 100 May units as event u1 and 40 June units as u2. A repeated delivery of u1 adds nothing. A late event u3 contributes another 30 May units because its occurrence period is May. The code does not use arrival order to redefine the customer's accounting period.

That rule must be visible to the people who answer billing questions. A dashboard grouped by ingestion day can be operationally useful while disagreeing with a usage statement grouped by service period. Label the two views and preserve the underlying timestamp evidence. Otherwise a legitimate late arrival looks like an unexplained change to yesterday's number.

Usage u1 adds 100 May units and correction c1 references it to remove 20 May units.
Figure 1. Executed ledger relationship: c1 references u1 within the same tenant and meter. Both records remain available to explain the May total. View full-size figure.

Stripe's usage-recording documentation distinguishes recorded usage from asynchronously aggregated summaries. Its current guidance directs new usage-based implementations toward Metronome, while documenting Billing Meters for existing integrations. Treat the vendor's actual product and ingestion contract as a separate integration decision. An application ledger cannot assume that an external dashboard immediately reflects every accepted delivery.

A correction should identify the fact it changes

The correction c1 removes 20 units from u1. It references the original usage entry, inherits its May attribution and leaves both records inspectable. Repeating c1 does not remove another 20 units. The resulting May total is 110: the original 100, minus the correction of 20, plus the late 30.

Four unique entries and their assigned usage periods
Ledger eventMeaningApplied changePeriod
u1Completed pages100May
u2Completed pages40June
c1 references u1Linked correction-20May
u3Late completion report30May

The input deliveries and applied ledger make that arithmetic reproducible. Three additional checks reject an unknown correction reference, a correction exceeding the original event's remaining units and a conflicting duplicate payload. The script exits with an assertion failure if those boundaries stop holding.

This model only allows negative corrections against a previously accepted usage entry in the same tenant and meter. A correction cannot borrow units from another customer or silently change a different meter. Real products may also need positive adjustments, cancellation reasons, approval roles or evidence retention. Define those as explicit event types and permissions instead of stretching the meaning of a negative usage number.

The ledger is not a payment processor. It does not calculate prices, discounts, tax or an invoice balance. Its narrower job is to explain which usage facts contribute to a period and why a correction changes that total.

Make the customer-facing explanation an acceptance criterion

A useful usage screen can answer more than "what is the total?" For a disputed period, it should identify the counted work, show any correction and explain whether late arrivals can still change the number. Access to detailed evidence must follow tenant permissions. A support agent should not need unrestricted raw event access to explain a single customer's adjustment.

For this fictional product, an acceptance review starts with the exact sequence in the fixture. Product and engineering should agree that the two duplicate deliveries add no units, that c1 adjusts May once and that the late May event remains attributable to May. A screen showing only a running aggregate cannot demonstrate those properties.

Six deliveries sum to 230 raw units; four unique applied entries produce May 110 and June 40.
Figure 2. Executed results: summing delivered payloads gives 230 units. The deduplicated ledger applies 150 units, split into May 110 and June 40. View full-size figure.

When evaluating implementation help, connect that review to the scope actually offered. Pharos Production's SaaS development with usage tracking and subscription billing covers SaaS billing and subscription workflows alongside tenant isolation and usage tracking. The page is relevant when assigning responsibility for this product boundary. Ask a delivery proposal to demonstrate the original event, linked correction and tenant-scoped explanation before accepting a total-only billing integration.

That is a requirement for evaluating proposed work, not evidence that a provider ran this fixture or achieved a particular billing outcome. The commercial page does not replace acceptance evidence from your own implementation.

Choose the closed-period policy before the first dispute

The example assumes both periods are open. Once a customer has received a finalized statement, changing a historical aggregate may create a second meaning for the same displayed period. Decide how a late event or correction is represented at that point: a separately identified adjustment, a reopened period under a defined process or another supported product workflow.

Whatever the chosen policy, retain the connection between the new action and its original usage evidence. Do not erase the old event merely to make a current total match. Also define who can submit a correction and how a repeated request behaves after a timeout. The separate API idempotency example explains why retry identity must survive uncertain responses.

Before release, reconcile the application ledger with the external usage system using stable event identifiers and a known processing boundary. Accepted locally, transmitted remotely and included in a vendor summary are different observations. A missing remote aggregate may reflect delayed processing, a rejected event or an integration defect; the local ledger alone cannot distinguish them.

The fixture results establish four applied entries, two duplicate deliveries and the resulting period totals. They leave invoice policy and vendor behavior untested. That separation gives the team a concrete starting point: first agree on the customer's billable facts, then prove that the production integration preserves them.

Sources

Documentation checked .

  1. Stripe: record usage with Billing Meters
  2. Stripe: record usage through the API
  3. Pharos Production: SaaS development scope

Continue the conversation

Comments (9)

  1. Dreamtsoft Editorial

    The completed-page definition should be visible to support. A worker attempt and a billable completion describe different events when retries are involved.

  2. Dreamtsoft Editorial

    A repeated identifier with changed content needs investigation. Treating it as an ordinary duplicate would hide a disagreement about the original usage fact.

  3. Dreamtsoft Editorial

    The late event belongs to its occurrence period under this contract. A view grouped by ingestion day needs a clear label so it does not appear to contradict the usage statement.

  4. Dreamtsoft Editorial

    Keeping the correction linked to its original entry makes the adjustment explainable. A lower aggregate alone would leave the customer asking which work was removed.

  5. Dreamtsoft Editorial

    Repeated correction delivery deserves the same retry check as the original usage delivery. The link identifies what changes; durable event identity controls whether it changes again.

  6. Dreamtsoft Editorial

    What should support show when a correction arrives after the period has closed? That product decision remains outside the open-period fixture and needs an explicit acceptance case.

  7. Dreamtsoft Editorial

    The tenant and meter scope should be checked for correction references as well as original entries. A valid identifier in another scope cannot supply the intended usage evidence.

  8. Dreamtsoft Editorial

    Local acceptance and inclusion in an external summary are separate checkpoints. A reconciliation view needs enough event identity to locate where a missing contribution stopped.

  9. Dreamtsoft Editorial

    The ledger explains units without establishing an invoice balance. Keep pricing rules separate when using this fixture to review an implementation proposal.

Leave a comment

Your name and comment stay in this page and are cleared after the spam check.

10–2,000 characters. Keep the discussion relevant to this article.

Spam protection verification
Spam protection loads when you begin the form.

JavaScript is required to use this form and its spam protection.