Earlier this year I worked with a company whose products are, at bottom, sensors — devices in buildings reporting what they see. The customers pay for what the devices do. And yet every month, someone assembled the invoices by hand: export the usage, paste it into a spreadsheet, apply the price book, hope nothing drifted.
This is the story of moving billing to where the data already was — and why the sensor, in a real sense, now sends the invoice.
The invoice didn't match the building
Manual billing fails quietly. The device fleet grows, the price book changes, a customer's contract has an exception someone remembers but the spreadsheet doesn't. Nothing crashes — the numbers just drift. The drift shows up as the two worst kinds of billing conversation: the customer who was overcharged and now questions every line, and the customer who was undercharged, which is revenue you earned and never collected and can never politely ask for.
The deeper problem is structural. The company already had the truth — every device streams telemetry into the platform. Billing just wasn't reading it. The invoice was a monthly reconstruction of a reality the system already knew, retyped by a person, with all the fidelity that implies.
Usage is already data
The fix reframes billing as a data problem: the reading that detects smoke is the same number the customer pays for. Once you accept that, the architecture mostly draws itself.
Telemetry lands in Snowflake as raw, immutable events. Rating models sit on top: for each customer, each period, each priced thing — how many devices, how many events, which tier — computed from the raw stream with the contract terms as inputs. The invoice is a report over rated usage. No exports, no retyping, and no difference between what the product did and what the bill says, because they read the same tables.
We replaced a paid integration layer in the middle of this with a small in-house service, which cut the platform's cloud spend by about 40%. The interesting part wasn't the saving; it was that deleting the middleman made the numbers easier to trust, not harder.
The rules that made it boring
Billing is one of those domains where boring is the goal. Four rules did the work:
- Rating is replayable. Every run is idempotent and can be re-executed for any past period from the raw events. When the price book changes, you re-rate the period — you never patch an invoice by hand.
- Every line item traces to readings. A customer asking "why this number?" gets a query result, not a meeting. Disputes mostly stopped happening once the answer was visible.
- Unbilled usage is an alert, not a surprise. If devices stream data that no contract covers, someone hears about it that week — not at year-end, when it has become awkward.
- Customers see what billing sees. The usage shown in the product comes from the same models the invoice is computed from, so there is nothing to reconcile later.
What I'd tell another team
If your product generates the very usage you charge for, billing is not a finance workflow that consumes engineering output — it is a reporting layer over data you already have. Build the raw stream, make rating deterministic and replayable, and let the invoice fall out of it. The month a sensor fleet sends its own invoices is the month billing stops being a meeting.
Muhammad Alnaqeeb is a senior software engineer in Cairo. He works on wallets, ledgers and fraud controls, most recently at Octane. Reach him at m@alnaqeeb.dev.
← More writing