In one sentence. ComputeFlux counts your usage inside a sealed enclave and writes a cryptographically signed summary to a public blockchain, so your bill becomes something you can check rather than something you have to accept.
Picture it like this. Two taxis. In the first, the driver tells you the fare at the end of the ride and holds the only record of the distance. In the second, the meter is sealed by an inspector and prints a stamped receipt anyone can audit. Essentially every software bill you receive today is the first taxi.
Why it matters. The problem isn't dishonest companies — it's a structural conflict of interest. Whoever measures the usage also collects the payment, and building independent measurement has always cost more than the overbilling was worth. This article is about making the measurement free to verify.
Interested in the SLA angle? Skip to on-chain failure accounting.
Billing systems carry a structural conflict of interest: whoever measures the usage also collects the payment. In traditional SaaS, customers accept the provider's metering because building independent measurement infrastructure costs more than the overbilling it would catch. In a decentralized AI gateway, where providers and consumers may be adversarial strangers, that calculation collapses.
ComputeFlux removes the trust requirement instead of asking you to extend it. All metering runs inside TEE enclaves, usage aggregates into cryptographically signed settlement batches, and the results anchor on-chain through DKG threshold signatures. The design also leans directly on Article 9: settlement transactions retry on the same cooldown-gated cadence, and the FailCount field this article examines is populated by exactly the error classification described there.
The Double-Spend Problem in Usage Metering
Metering a single API call sounds trivial: on request arrival, record a counter; on response completion, increment usage fields. But distributed systems transform trivial operations into distributed consensus problems. Consider a relay node that receives an API request, increments the user's token counter, and then crashes before forwarding the response. The upstream LLM provider processed the request, consumed GPU compute, and expects payment. The user retries, hitting a different relay node that records a second increment. The user is charged twice for one effective call.
ComputeFlux's defense has two layers.
First, nothing is recorded until the upstream provider returns a response with a measurable token count. The relay handler takes the completion, pulls prompt_tokens and completion_tokens from the response body's OpenAI-compatible usage field, and only then pushes a usageRecord into an asynchronous channel. Crash before the response arrives and nothing is recorded at all. Crash after recording but before the response reaches the client, and the relay eats the cost — the user never got the output, so the user isn't charged. That asymmetry leaks a little provider revenue, but at a 99.9%+ success rate it amounts to roughly 0.1%, which is nothing against the reputational cost of overcharging.
Second, channel buffering with keyed merging blocks the distributed double-count. Every usageRecord carries a composite key of (tokenID, routeID, modelID). A background goroutine drains the channel once per second, accumulates records into a batch map, and merges same-key records by summing their token counts and success/failure counters. Should two parallel relay handlers ever produce records under the same key — a bug, not normal operation — the merge collapses them into one. The channel doubles as a natural batching point: draining once per second turns many individual writes into far fewer aggregated ones, pushing PebbleDB write amplification well below the per-request baseline.
The 1-Second Flush Interval: Data Loss Risk vs. Write Amplification
The flush interval is a direct trade-off between two failure modes. Flushing every record synchronously (0ms batching) eliminates in-memory data-loss risk but maximizes disk I/O: each API call produces one PebbleDB write, each write hits the memtable, and LSM-tree compaction amplifies writes by 10–30x depending on workload. Flushing once per settlement cycle (5 minutes) minimizes write amplification but exposes up to 5 minutes of usage data to loss if the enclave crashes — potentially hundreds of thousands of tokens of unrecoverable billing data.
One second is where the data-loss risk becomes economically acceptable. At 1,000 concurrent API calls across all models, a one-second window captures a substantial share of in-flight completions, and a crash between flushes loses at most that second's worth — plausibly hundreds of thousands of tokens, depending on prompt/completion ratio and concurrency. At $0.15–$0.60 per million tokens, that's a fraction of a dollar of unrecoverable billing.
Set against the crash itself, it's a rounding error. An enclave restart takes seconds, and during those seconds requests are rejected or queued. The reputation and churn cost of that dwarfs the billing gap.
Write amplification is the cost on the other side. PebbleDB's LSM-tree writes each flush into the active memtable. When that fills — 64MB by default — it becomes an immutable SSTable and triggers compaction: read the overlapping SSTables, merge them, write a new sorted file. Over its lifetime, each byte of user data can be physically written 10–30 times.
So a one-second flush of a few hundred KB of billing data produces correspondingly more physical I/O than that. Stretch to five-minute flushes and each one writes an order of magnitude more data in a single burst, which can spike latency visibly at the consensus layer if compaction lands on top of block finalization. One second smooths the same work into a steady trickle that leaves consensus alone.
Why 5-Minute Settlement Instead of Real-Time
If billing data is already in PebbleDB, why not settle every block and get near-real-time on-chain accounting? The answer involves transaction overhead, DKG signing coordination, and nonce management, even if the exact costs are harder to pin down than the interval itself.
Every settlement transaction sent to the Polkadot relay chain pays a fixed overhead — signature verification, base extrinsic weight — on top of its calldata. Packing many aggregated usage records into one transaction, one per active user-model-route combination in the window, spreads that overhead across all of them. Settle every block instead and each transaction carries far fewer records while paying the same fixed cost, so you pay the overhead far more often per unit of data settled. The 5-minute window exists to keep that amortized per-record cost down.
DKG signing adds a second constraint. Each settlement needs a fresh threshold signature from a quorum of DKG nodes, and generating and collecting partial signatures requires all signers to be online and responsive. Signing on every block would tie settlement liveness tightly to DKG infrastructure liveness — any signer hiccup would stall settlement immediately. Batching into 5-minute windows gives the DKG ceremony a much larger time budget per settlement, so a brief signer outage can be absorbed without missing a cycle.
Nonce management is the subtler factor. Settlement transactions are submitted as system calls with their own per-contract nonce counter (see tee-chain/tx_nonce.go), which every node must agree on to avoid conflicting submissions. Settling every block would advance that nonce far more frequently, creating more opportunities for disagreement to surface; batching into 5-minute windows means fewer, larger settlement transactions and correspondingly fewer nonce values consumed per unit of settled data.
The FailCount Field: Economics of SLA Enforcement
The FailCount field answers a question pure token-based billing can't: was the service actually delivered? As described in Article 9, when a relay node proxies to an upstream provider and gets back a 429, a 503, or a timeout, the consumer pays nothing — no tokens were consumed. But the event still matters economically, and this is where that classification work pays off.
FailCount tracks failed requests per user-provider-model-route combination within each settlement window. Recorded on-chain and immutably tied to the provider's identity, it does three jobs.
SLA enforcement. A provider's contract guarantees 99.5% uptime; FailCount shows 2% of requests failing in a window. The governance contract can now act on that — slashing staked tokens, cutting routing weight. Without an on-chain record, SLA enforcement stays off-chain and, in a permissionless setting, legally unenforceable.
Provider reputation. The routing optimizer reads historical FailCount from chain state and computes an effective reliability score. Low-failure providers get priority; high-failure providers get demoted. The market self-corrects, and unreliable providers lose traffic and revenue. On-chain immutability is what stops a provider from quietly rewriting its own failure history — trivial to do if the counts were self-reported.
User-side analytics. A consumer watching 10% of their requests to a model fail can switch providers programmatically. The data is on-chain, permissionlessly queryable, and cryptographically attested by the DKG-signed settlement transaction. No API key, no subscription, no trusted dashboard.
The distinction from Article 9 carries through unchanged here: context.Canceled errors never increment FailCount, which prevents a malicious client from damaging a provider's reputation simply by connecting, sending a request, and immediately disconnecting.
PebbleDB + On-Chain Dual Storage Rationale
The architecture keeps two copies of billing data: PebbleDB (within the enclave, on local NVMe storage) and the Polkadot relay chain (globally replicated, consensus-secured). They serve different purposes with different consistency guarantees.
PebbleDB is the operational store. The relay handler reads it at request time to check a user's remaining credit — GatewayGetCredit in the gateway module computes credits - credit_useds — and to enforce rate limits. The once-per-second flush goroutine writes to it. The settlement goroutine reads from it to build each 5-minute batch.
Its consistency model is crash-safe but not Byzantine-resistant on its own. A malicious operator with physical access to the NVMe drive could attempt to modify the sealed PebbleDB files. What stops them is layered: SGX sealing keys block offline tampering with committed data, the enclave's memory encryption covers online access, and filesystem encryption covers offline access.
The relay chain is the settlement store — queried by anyone to verify a settlement batch was accepted by the DKG signers and committed to the chain. Once finalized (roughly 30 seconds under Polkadot's GRANDPA finality), it's immutable under the relay chain's full economic security — billions of dollars of staked DOT. It doesn't store per-request granularity (prohibitive gas cost), but it stores the aggregated, cryptographically signed batch, creating a verifiable root of trust for all billing data.
The two-store split is a fundamental blockchain pattern: hot state in a fast local database, cold verifiable state on a replicated ledger. PebbleDB answers millisecond queries at request time. The relay chain handles dispute resolution, auditing, and economic finality. Between them sits the DKG-signed settlement bridge — the one component that must be secure, correct, and live for any of this to work, and whose behavior under failure is precisely what Article 9 describes.
Key Takeaways
- Nothing is billed until the provider returns a real token count. A crash before the answer arrives charges you nothing. A crash after the count but before delivery is absorbed by the network, not the user — a deliberate asymmetry costing roughly 0.1% of revenue and worth every basis point against the reputational cost of overcharging.
- Usage is written once a second, and that number is a considered trade. Writing instantly multiplies physical disk writes by 10–30×. Writing every five minutes risks losing real money in a crash and dumps a burst of I/O that can disturb block production. One second is where both curves are tolerable.
- Settlement batches every five minutes for three separate reasons. Each on-chain transaction pays a fixed cost regardless of how much it carries; threshold signing needs a quorum awake and responsive; and fewer transactions mean fewer chances for validators to disagree about ordering.
- Failures are recorded on-chain, which is what makes an SLA mean anything here. In a permissionless network, off-chain uptime claims are unenforceable. A provider cannot quietly revise a reliability history that lives on a public ledger.
- Two stores doing two jobs. A fast local database answers "does this user have credit right now?" in milliseconds. A public chain answers "prove what I was charged" to anyone, forever. Hot state local, verifiable state replicated.
Billing establishes what's owed on ComputeFlux's own chain. But the money — the deposits users bring in and the earnings providers take out — lives on a different chain entirely, and moving information between two blockchains is the most dangerous thing in this entire series.
Next — Article 11: Relay — Cross-Chain Sync: bridges have lost over $2 billion to attackers. Here's how to build one with less to steal.