Your Billing System Can't Count Small Enough
Your billing system was built to count dollars. Maybe cents. It was not built to count $0.000001.
That's fine. Nobody thought you'd need to. Then AI happened, and suddenly you're charging per token, per inference, per millisecond of GPU time — and the smallest unit of value your product delivers is smaller than the smallest unit your billing stack can represent without rounding it to zero.
Congratulations. You have a nanotransaction problem.
What Is a Nanotransaction?
A nanotransaction is any billable event so small that standard currency precision loses money when you try to count it. We're talking about charges in the range of:
- $0.000001 — GPT-3.5 Turbo input tokens at current rates
- $0.00000001 — high-volume API routing fees
- $0.00000000025 — Claude Haiku input tokens at published rates
- $0.000000000001 — byte-level metering in some infrastructure products
ISO 4217 says USD has 2 decimal places. That means your billing system — if it's storing amounts as integers in cents — literally cannot represent $0.000001. It rounds to $0.00. Times a million API calls, that's a dollar you just gave away. Times a hundred million calls, that's $100. Times a billion, you can do the math.
Most companies discover this problem the same way: they launch a usage-based pricing tier, watch revenue come in 20% lower than their metering suggests, and spend three weeks convinced the metering is wrong. The metering is fine. The billing is rounding.
The Standard Fix (Which Doesn't Work)
The obvious fix is to aggregate before billing: buffer events, batch them up, emit one charge per customer per hour or per day at standard cent precision. Problem solved.
Except it's not. You've just moved the problem. Now you're rounding at the aggregation boundary instead of the event boundary — still losing precision, just later. And you've introduced latency: a customer burns $500 of credits in an hour and your system won't know until the next batch runs. Good luck with spend controls.
The slightly better fix is to store amounts as floating-point. Please don't do this. Floats are not money. IEEE 754 will hand you a $0.10 charge that is actually $0.09999999999999998, and that error will compound across millions of transactions until your reconciliation process starts producing numbers that confuse everyone, including you.
The Actual Fix
You need two types: one for accumulation, one for invoicing. They serve different purposes and require different precision.
Accumulation type: an integer at 10⁻¹² precision from the major unit. For USD, that's one trillion units per dollar. Store it as a signed 128-bit integer — i128 can represent $170 septillion before overflowing, which is more than enough even if your customers are nation-states. Every event contributes its raw integer value to the accumulator. No rounding occurs.
Invoice type: standard ISO currency precision — cents for USD, whole units for JPY, fils for KWD. Rounding happens exactly once, when you generate the invoice line item.
The rule is simple: accumulate at full precision, round once at the invoice boundary. Every extra rounding step is revenue loss you've voluntarily accepted.
The Math That Actually Matters
The first approach is how most billing systems work. The second is how billing systems should work. The difference is $1 in this example. At OpenAI's traffic levels, it's millions of dollars per day.
This is the key insight: rounding is not commutative with summation. The order of operations matters. Sum all your raw values first, then round. Never the other way around.
Why Scale=12?
The number 12 isn't arbitrary. It's the smallest power of 10 that covers every real-world sub-cent billing scenario with headroom:
- Claude Haiku at $0.00000000025/token = 250 raw units. Exact.
- Byte-level storage at $0.000000000001/byte = 1 raw unit. Exact.
- Any rate you're likely to publish for the next decade fits cleanly.
Scale=9 (nanocents) handles most AI billing. Scale=12 (picocents) covers the entire addressable space. The cost of going wider is zero — a 128-bit integer is the same size whether you use 9 or 12 decimal places, and the max representable value is $1.7 × 10²⁶, which is more money than has ever existed.
Global Currencies Add a Wrinkle
Different currencies have different ISO precision — USD has 2 decimal places, JPY has 0, KWD has 3. Your accumulation type needs to handle this correctly at conversion time.
The solution: store all currencies at the same internal scale (12 from major unit), but round to the currency's native precision at invoice time. $1.2345 worth of nano-units converts to $1.23 for USD, ¥1 for JPY, and 1.234 KWD — all from the same integer representation, all correct for their currency's conventions.
The table of zero-decimal currencies is longer than you think: JPY, KRW, VND, IDR, UGX, RWF, XAF, XOF, XPF. Get this wrong and you'll charge ¥12300 instead of ¥123. Your Japanese customers will notice.
Who This Matters To Right Now
If you're billing per token, per inference, per API call, per GPU millisecond, per byte stored, or per message routed — this matters to you now. If you're not yet but plan to introduce any metered pricing component, build this correctly from the start. Retrofitting a billing system to handle nanotransactions after you've already shipped is a special kind of miserable.
The companies getting this right — Anthropic, OpenAI, AWS — have purpose-built accumulation layers that never touch float arithmetic and round exactly once. The companies getting it wrong are quietly losing 2–5% of metered revenue to rounding errors and haven't figured out why actuals are always a little under forecast.
Your billing system should be able to count $0.000000000001. If it can't, you're leaving money on the table — at exactly the moment when the things you're billing for are getting cheaper and more granular every quarter.