Why this matters
- Conflating linearizability and serializability is a common senior interview trap — they apply at different granularities.
- Distributed locks and leader election need linearizable registers; multi-statement transfers need serializable transactions.
- Jepsen and formal tests verify linearizability claims — marketing "strong consistency" without specifying which guarantee is a red flag.
- ShardPay's architecture uses linearizable single-account updates inside serializable cross-table transactions on one shard.
Two ordering guarantees
A balance read immediately after a transfer must return the new value — that is linearizability on the account register. A batch job that debits one account and credits another on the same shard must execute as if no other transaction interleaved — that is serializability on the transaction schedule.
Linearizability is about individual operations and real-time ordering. Serializability is about multi-operation transactions and equivalent serial execution. ShardPay needs both, at different layers of the stack.
Definitions
- Linearizability — Each operation appears to take effect instantaneously at some point between its invocation and response, respecting real-time order. ShardPay's
GET /balanceafter a successfulPOST /transfersmust return the post-debit balance — not a value from before the transfer completed. - Serializability — The result of concurrent transactions is equivalent to some serial execution of those transactions. ShardPay's ledger applies
debit(A) + credit(B)inside one transaction so no concurrent transfer can observe A debited but B not yet credited. - Strict serializability — Serializable order that also respects real-time precedence. ShardPay's single-shard transfer path targets strict serializability: if transfer T1 completes before T2 starts, the serial order must place T1 before T2.
- Compare-and-set (CAS) — Atomic read-modify-write primitive underpinning linearizable updates. ShardPay's optimistic balance update uses
UPDATE accounts SET balance = :new WHERE id = :id AND balance = :expected— the database CAS enforces single-writer semantics per row.
Linearizability at the register layer
Distributed systems literature often models a key-value register. ShardPay's account balance is logically one register per accountId. Leader-based replication with quorum reads/writes provides linearizable access when configured correctly.
Walkthrough: Concurrent balance reads during transfer
- Account
Ahas balance $1,000. - Thread 1 starts transfer debiting $200 at wall time T0; commit completes at T1.
- Thread 2 issues linearizable read at T0.5 (during transfer). It may return $1,000 or wait — never $800.
- Thread 3 issues linearizable read at T2 (after commit). It must return $800.
- Any read that overlaps the write interval either sees before-state or after-state — never an impossible middle.
// Linearizable balance read via leader + quorum (conceptual)
public long readBalanceLinearizable(String accountId) {
return leader.readWithQuorum(accountId, ReadConcern.QUORUM);
}
// Linearizable update via CAS on leader
public boolean debitIfSufficient(String accountId, long amount, long expectedBalance) {
return leader.compareAndSet(accountId, expectedBalance, expectedBalance - amount);
}
Serializability at the transaction layer
Within one shard, ShardPay uses MVCC with serializable isolation for transfer transactions: debit source, credit destination, insert audit row, bump daily limit counter — all commit or abort together.
Transaction-level guarantees
- Serializable isolation — Prevents anomalies like write skew where two transactions each read a condition, both pass, and together violate an invariant. ShardPay rejects concurrent transfers that would together exceed a daily limit even if each alone looked fine at read time.
- Snapshot isolation (weaker) — Each transaction sees a consistent snapshot; write skew still possible. ShardPay moved from snapshot to serializable on the ledger after a write-skew incident on shared merchant limit rows.
- Distributed serializability — Serializable across shards requires coordination (2PC, saga, or single-shard design). ShardPay colocates both legs of a transfer on one shard via
hash(min(accountA, accountB))to keep serializability local. - Linearizable but not serializable — Individual CAS ops can be linearizable while a multi-step workflow across keys is not serializable without a transaction boundary. ShardPay wraps multi-row updates in explicit DB transactions, not chains of separate CAS calls.
Example: Write skew on daily limits
Two transfers of $30,000 each run concurrently on the same merchant account with a $50,000 daily cap. Under snapshot isolation, both read dailyTotal=$0, both pass the check, and both commit — $60,000 exits. Under serializable isolation, one transaction aborts with SERIALIZATION_FAILURE; ShardPay's client retries with backoff. The merchant sees one success and one "limit exceeded" — correct behavior.
Testing and operating strong guarantees
Verification
- Jepsen — Fault-injection framework that checks linearizability under partitions and crashes. ShardPay runs Jepsen suites against staging ledger shards before major replication upgrades.
- Formal register tests — History checker builds a graph of operations and searches for linearization points. Used in CI for ShardPay's custom in-memory ledger prototype.
- DB isolation levels — Postgres
SERIALIZABLE, Cockroach serializable default — know what your engine actually provides. ShardPay's per-shard Postgres runsdefault_transaction_isolation = serializable. - When to relax — Analytics replicas use
READ COMMITTED— no financial writes. Document the boundary so engineers do not run ad-hoc fixes on the wrong connection pool.
Quick recall
Everything you need if you only revisit this box.
- Linearizability is per-object real-time order; serializability is about transaction interleaving.
- ShardPay uses linearizable registers inside serializable single-shard transactions.
- Cross-shard serializability needs sagas or colocation — payments colocate by account pair hash.
Test yourself
Answer these before moving on — recall is what makes it stick.