Field notes
Why your true-up ledger should be append-only
Every invoice should be explainable months later, from the terms and usage as they were at the time. That's only possible if nothing you've already billed gets overwritten.
About these field notes. They draw on public discussions with RevOps, billing and NetSuite practitioners in October 2026, in which several people described how their teams run usage true-ups today. We paraphrase and don't name anyone. The worked examples are illustrations we built to show the mechanics, not any company's real figures.
The design practitioners converge on
An engineer who has built true-up logic for several SaaS companies described the setup that kept working. Contract terms stay in the CPQ ("what did we agree"). Usage stays in the warehouse. A small, separate process does the monthly arithmetic and sends one number per contract to the billing system. The billing system never has to understand the drawdown rules.
The part they stressed most: once a period is invoiced, its ledger row never changes. If something was wrong, the correction is a new row in the next open period.
Four tables
| Table | What it holds |
|---|---|
| Contract segments | Terms per contract, one row per segment: start, end, commit, included units, rollover rule, rates. An amendment adds a segment; it never edits one. |
| Usage | Line-level usage from the warehouse: contract, date, quantity. |
| Drawdown ledger | One row per contract per period: opening balance, usage, drawn, rolled over, rollover expiry, expired, closing balance, invoiced date. |
| Billing out | The only thing the billing system sees: one line per contract per period, plus any adjustment lines. |
Running state, such as remaining commit or next expiry, belongs in the ledger, not the CRM. If sales or customer success need to see it, copy a read-only summary back to the contract record.
Late usage after the invoice went out
A contract includes 10,000 units a month, overage at $1.20. January closes with 10,200 units, and $240 of overage is invoiced on 2 February. On 5 February, 150 more January units arrive from a delayed export.
| Line | Period | Units | Amount | Status |
|---|---|---|---|---|
| Overage | January | 200 | $240 | Invoiced 2 Feb, never edited |
| Adjustment for January | February | 150 | $180 | On the next open invoice, labelled with the period it corrects |
The January invoice still matches what the customer received. February shows exactly what changed, and why.
Computed with our drawdown engine, which reprices the correction at January's rate and places it on the first period not yet invoiced.
What append-only gets you
- Replays: rerun the arithmetic at any time and confirm it reproduces every invoice already sent. If it doesn't, the difference is a visible adjustment, not a silent change.
- Explainable invoices: any line traces back to a segment, a usage set and a ledger row.
- Safer amendments: new terms add a segment; past periods stay put. See amendments.
- Cleaner audits: auditors and acquirers can follow usage revenue period by period without asking you to reconstruct a spreadsheet.
How we use this design
TrueUpp's reconciliation engine is built this way: contract segments, rollover lots that each keep their own expiry, amendments as new segments, and an append-only billing output with replay adjustments. It's what lets an audit show, for any period, what was owed under the contract, what was invoiced, and exactly where the two part ways.
Want your invoices replayed against your contracts?
We'll rebuild the ledger for a sample of accounts from the contracts and usage, and show any period where what was invoiced differs from what was owed. Free, within 48 hours of complete files.