skip to content
arpit agrawal
decision1 min

Two-phase commit for credits, not sagas

Why the billing system holds a reservation before any GPU work starts.

status
accepted
decided
q2 2026
considered
sagas · ledger-only
systems
go · aurora postgresql

A job charges credits when it runs, but the job runs on one system and the balance lives on another. Either side can fail after the other has already committed.

Reserve credits before any GPU work starts, then settle or release the reservation once the job ends. Both steps are transactions in the same database.

go
tx.Prepare(ctx, reserve)   // hold credits
job.Run(ctx)
tx.Commit(ctx)             // or Rollback on failure

Balances can never go negative from in-flight work. The cost is an extra round trip per job and a sweeper that releases reservations left behind by crashed workers.