Database DesignTransaction Isolation LevelsHard⏱️ ~3 min

Serializable Isolation: Implementation Strategies and Costs

Serializable isolation guarantees that concurrent transactions produce results identical to some serial execution order, preventing all anomalies including write skew. Production systems implement this via three main strategies, each with distinct performance profiles. Two Phase Locking (2PL) acquires read and write locks and holds them until commit, adding predicate or index range locks to prevent phantoms. This approach blocks conflicting transactions and risks deadlocks but provides strong guarantees with predictable (if sometimes long) wait times. Serializable Snapshot Isolation (SSI) is the modern alternative, used by PostgreSQL and FoundationDB. Transactions run on MVCC snapshots but the database tracks read write dependencies between concurrent transactions. If a dangerous structure is detected (a cycle in the dependency graph indicating potential non-serializable behavior), one transaction aborts. Readers remain non-blocking and performance is excellent when contention is low. However, at high write rates on hot keys (over 5,000 updates per second), abort rates can climb to 5 to 10 percent or higher, requiring careful application retry logic and narrow transaction scopes. Time or order based serializability, exemplified by Google Spanner with TrueTime, assigns globally ordered timestamps using tightly bounded physical clocks. Each commit waits out the clock uncertainty (epsilon, typically under 7 milliseconds in a single region) to ensure no transaction with a later timestamp can have started earlier in real time. This provides strict serializability (external consistency) at the cost of commit wait latency. Cross region transactions pay at least one wide area network round trip (80 to 150 milliseconds) plus commit wait. Apple FoundationDB uses optimistic concurrency with conflict ranges rather than time, achieving single region median latency of a few milliseconds but seeing 10 to 20 percent abort rates under coarse read/write sets. The trade-off is always consistency versus throughput and latency. Serializable isolation is essential for critical invariants like monetary transfers, unique resource allocation, and inventory management. For read heavy analytics, dashboards, or approximate aggregates, Read Committed or snapshot isolation on read replicas is usually sufficient and delivers 2 to 5 times higher throughput. In practice, many systems use Serializable for a small subset of write paths (the "critical section") and lower isolation elsewhere, tuning per transaction based on correctness requirements and acceptable retry rates.
💡 Key Takeaways
Two Phase Locking holds read and write locks until commit and adds predicate locks for phantoms, blocking conflicting transactions and reducing throughput 2 to 5 times under contention
Serializable Snapshot Isolation (PostgreSQL, FoundationDB) tracks read write dependencies and aborts on cycles, keeping reads non-blocking but seeing 5 to 10 percent abort rates at over 5,000 updates per second on hot keys
Google Spanner TrueTime provides strict serializability via commit wait (typically under 7 milliseconds) plus clock uncertainty, cross region transactions pay 80 to 150 milliseconds for wide area network round trips
Apple uses FoundationDB for iCloud metadata with optimistic concurrency, achieving few millisecond median latency but 10 to 20 percent aborts under coarse conflict ranges
Most production systems use Serializable selectively for critical write paths (money transfers, unique allocation) and Read Committed or snapshots for read heavy endpoints to gain 2 to 5 times throughput
Operational practice: monitor abort/retry rates for SSI, lock wait times and deadlocks for 2PL, commit wait duration for time based systems, and keep transactions short with narrow read/write sets
📌 Examples
PostgreSQL Serializable: Banking transfer reads two account balances (snapshot), updates both, SSI detects concurrent transfer conflict and aborts one for retry
Google Spanner: Advertising auction transaction commits with 5 millisecond commit wait in single region, cross continent auction takes 120 milliseconds (80 millisecond RTT plus 7 millisecond wait plus consensus)
FoundationDB at Apple: Metadata update with read set spanning 100 keys sees 15 percent abort rate, narrowing to 10 keys drops aborts to under 3 percent
MySQL InnoDB Serializable with 2PL: Hot secondary index range query (top 100 posts by score) acquires gap locks, serializing concurrent inserts and dropping insert throughput from 8,000 per second to 2,000 per second
← Back to Transaction Isolation Levels Overview