Engineering
All money is int64: nano-USD billing for LLM tokens
CleverCrow bills people for LLM tokens. Tokens are priced in fractions of a fraction of a
cent, runs are funded by multiple backers splitting costs pro-rata, and unspent money is
refunded down to the last unit. If any of that math runs through floating point, someone
eventually gets a balance that says 4.999999999999 and your support inbox
gets a ledger-audit request you cannot cleanly answer.
So the platform has one rule: all money is int64 nano-USD,
where 1 USD = 1,000,000,000 nano-USD. Every wallet balance, ledger entry, reservation,
pool aggregate, database attribute, and internal RPC field. There is no float on the
money path. This post is why that unit, and where the two deliberate exceptions live.
Why nano, specifically
Cents are the classic integer-money unit, but LLM rates don't fit in cents. The smallest rate we bill against is Anthropic's Haiku cache-read tier at $0.10 per million tokens. Per token, that's $0.0000001, a tenth of a microdollar. In cents it's a repeating decimal of a unit; in nano-USD it is exactly 100.
$0.10 / 1,000,000 tokens = 100 nano-USD per token (exact)
$3.00 / 1M (sonnet input) = 3,000 nano/token (exact)
$15.00 / 1M (sonnet output)= 15,000 nano/token (exact)
Every published per-million-token price across every model we support is an integer
number of nano-USD per token. Token math becomes pure integer arithmetic
(tokens × rate) with no accumulating rounding error, ever. A phase that
bills 1,372,904 cache-read tokens costs exactly 137,290,400 nano-USD, and ten thousand
such phases sum to exactly what they should.
Headroom: int64 tops out around 9.2 × 10¹⁸ nano-USD ≈ $9.2
billion. No single balance or daily volume on a funded-issues platform gets
within sniffing distance.
Floats may exist in exactly two places
Banning floats outright just moves the bug to the UI. The rule instead names the two boundaries where float-USD is allowed, and makes everything else a code-review rejection:
-
Display surfaces. UI labels, log fields, GitHub markdown. Convert at
the format call site (
money.ToFloatUSDin Go,nanoToUSDin TypeScript), render, and throw the float away. It never flows back in. -
Form inputs. An
<input type="number">hands you a JavaScriptNumberwhile the user types. Convert to integer units on submit; the float never touches storage or an RPC payload.
Notably not on the list: Stripe. People assume the payment processor is a
float-USD boundary; it isn't. Stripe's API is integer cents end to end
(unit_amount, Charge.amount, Refund.amount).
Nano-USD to cents is one integer conversion. The only USD-as-decimal strings near Stripe
are in its metadata fields, kept for humans reading the Stripe dashboard; they're
derived from the integer math and parsed back to integers on entry, never consumed as
floats.
Fees and splits without a decimal in sight
Backers fund a run as a pool, and each phase's cost is split pro-rata with a 20% platform fee on top. The fee rate is stored as integer basis points (2,000 bp), so the gross-up is integer all the way down:
gross = cost × (10,000 + 2,000) / 10,000
The pro-rata split multiplies before it divides (through a big-int intermediate, since
gross × committed can overflow), truncates once at the final divide, and
applies a 1¢ per-backer floor so a tiny phase never rounds a backer's contribution to
zero. The floor means the sum of debits can exceed gross by at most (N−1)¢ on a
many-backer micro-phase, a documented, bounded property, absorbed as margin and chosen
deliberately over "some backers visibly paid nothing."
Rate changes never rewrite history
One more invariant makes the ledger auditable: cost is stamped at append time. When a phase completes, its cost in nano-USD is computed against the current rate table and written onto the usage record. Reads prefer the stamped value. So when a provider cuts prices and we update the rate table, every past run's total stays exactly what the backer was actually charged; a rate edit can move the future, never the past.
The payoff
Every balance on the platform is a sum of integers. Refunds are
reserved − debited, exactly. The reconciler compares Stripe's integer cents
against the ledger's integer nanos and the only acceptable difference is zero. When a
backer asks "where did my $5 go," the answer is an itemized list of integers that adds up,
every time, to the nano.