LSM Trees
Why LSM trees (sequential writes versus B-tree page updates), memtables and the commit log, SSTables with block indexes and Bloom filters, the read path, compaction strategies (size-tiered, leveled, time-window, incremental), tombstones, amplification and the RUM conjecture, caches, and RocksDB as the reference implementation.
Writes in memory, merges in the background
B-trees (MySQL and Postgres courses) update pages in place: a write may touch a random page. LSM trees turn every write into an append, then pay the cost later in compaction. Fast writes now, merge work later.
Compaction strategies and tombstones
| strategy | how | good for | cost |
|---|---|---|---|
| size-tiered (STCS) | merge SSTables of similar size | write-heavy workloads | reads touch more files; temporary 2× disk space |
| leveled (LCS) | levels of non-overlapping runs, each 10× larger | read-heavy, updates | more write amplification |
| time-window (TWCS) | compact within time buckets; drop whole old buckets | time series with TTLs | out-of-order writes break the buckets |
| unified / incremental (newer) | adapts between tiered and leveled | mixed workloads | newer, fewer operational war stories |
Tombstones: a delete writes a marker that hides older values until compaction removes both. Many deletes (queue-like workloads) leave tombstones that every read must skip; reads scanning thousands of them become slow and Cassandra warns or fails (tombstone_failure_threshold). RocksDB, Facebook's embeddable LSM engine, is the reference implementation and powers many databases (CockroachDB's Pebble is a Go descendant, MyRocks, Kafka Streams state stores).