Coin or account model

In the account model a payment changes a stored balance. In the coin model it creates an unspent output, and a balance is the sum of outputs. 4,000 payments/s to one account stop near 2,500 updates/s on one row, and separate outputs do not wait for each other.

Play a level

See it on the board

The same traffic runs on two boards. The simulator measured both when this page was built.

Board to show
SQLSQLUsersPartner appsPostgres4 vCPU · 4 GB
SQLSQLUsersPartner appsPostgres4 vCPU · 4 GB
One balance row for the merchant: misses a goal
SQLSQLUsersPartner appsPostgres4 vCPU · 4 GB
SQLSQLUsersPartner appsPostgres4 vCPU · 4 GB
Outputs spread over many rows: meets the goals
See it on the board
Measure Goal One balance row for the merchant Outputs spread over many rows
p99 latency (Payments) under 100 ms 10.1 s Fail 26 ms Pass
Error rate (Payments) under 0.1% 79% Fail 0% Pass
Data age under 5 s 0 ms Pass 1 s Pass
Monthly cost 16 USD/mo 16 USD/mo

Key numbers

Default part values from the catalog. The mini board has 4,000 payments/s to one merchant.
NumberValue
Writes per second, one database vCPU2,500 writes/s
Entries per second, one ledger15,000 ops/s
Disk sync time for one commit0.4 ms
One balance row or many outputsTap or press Space to change the money model

Coin model · writes that wait for one row: 0 more each second

How it works

Two models can hold the same money. In the account model each owner has a balance in a row. A payment reads the row, adds the amount and writes it back. In the coin model each payment creates a new output, a record of an amount that can be spent once. A balance is the sum of the owner's unspent outputs.

The models behave differently under load. In the mini board card payments settle into one merchant at 4,000 payments/s, and payments need p99 below 100 ms. In the account model all of them update one balance row. A row takes one update at a time, so it stops near 2,500 updates/s, and the queue grows.

In the coin model each payment writes a new row. The writes spread over many rows and partitions, and they do not wait for each other. The merchant still needs a balance: it reads the sum of its outputs, and the sum can be a few seconds old. The mini board accepts a balance that is no older than 5 s, and it computes it in the background.

The coin model has costs. A balance read needs a sum, and spending needs to pick outputs and make change. The account model is simpler for the user and for the code.

An account can also be sharded into many sub-balances, which brings back the same effect.

In the levels you choose the model from the hot account and the read needs.