The full picture
| Serializability | Linearizability | Strict serializability | |
|---|---|---|---|
| Scope | multi-object transactions | single object/key | multi-object transactions |
| Orders by | some serial order | real time | real time |
| Legal to return stale? | yes (a valid serial order may be old) | no | no |
| Typical implementation | 2PL, SSI, MVCC | consensus/quorum per key | consensus + a clock (TrueTime, HLC) |
| Seen in | Postgres SERIALIZABLE | etcd, ZooKeeper, DynamoDB reads | Spanner, CockroachDB |
- The classic gotcha, stated concretely: a serializable database is allowed to run your read-only transaction as if it had executed an hour ago — no anomaly, no violation. If your requirement is 'I must see the payment that provably completed before my request started', serializability alone does not give it to you; you need the real-time clause.
- Why the two are so often conflated: single-object linearizable stores (etcd) and multi-object serializable stores (Postgres) rarely appear in the same sentence, so people assume 'strong = strong'. Distinguishing scope (one key vs many) and ordering (any serial order vs real time) is the whole answer.
- Isolation levels are the practical version of this: READ COMMITTED, REPEATABLE READ, SNAPSHOT, SERIALIZABLE — each removes anomalies (dirty read, non-repeatable read, phantom, write skew). Write skew is the one worth naming: snapshot isolation permits it (two doctors both go off-call because each read the other as on-call), which is exactly why SSI exists.
- Cost ordering to keep in your head: snapshot < serializable < strict serializable. Spanner pays for the top of that ladder with GPS/atomic clocks and commit-wait — literally waiting out clock uncertainty. That's how expensive real-time ordering is.