B-Tree vs. LSM-Tree
B-tree and LSM-tree tradeoffs for reads, writes, compaction, and storage layout.
B-trees and LSM-trees solve the same broad problem: keeping large datasets searchable on storage that is much slower than memory. They differ in how they organise writes, how they serve reads, and where they pay maintenance cost. Understanding that tradeoff explains why different databases behave so differently under the same workload.
How B-trees organise data
A B-tree keeps keys in sorted order across fixed-size pages. Reads follow the tree down to the relevant leaf, which makes point lookups and range scans efficient. Updates happen in place, so the structure stays queryable without extra merge work.
This is why B-trees are common in general-purpose relational databases. They handle mixed workloads well, especially when applications need ordered traversal, secondary indexes, and predictable read latency. The downside is that random writes can cause page splits, fragmentation, and more direct I/O work on busy storage paths.
How LSM-trees organise data
Log-Structured Merge trees optimise for write throughput. New writes first land in memory and append-friendly storage structures. Later, background compaction merges sorted files into larger levels. This turns many small random writes into fewer sequential operations, which is attractive for write-heavy systems.
The cost appears elsewhere. Reads may need to consult multiple files across levels unless metadata or Bloom filters can rule them out. Compaction also consumes CPU and I/O, and if it falls behind, latency can become spiky.
Read paths versus write paths
A simple summary is that B-trees tend to make reads straightforward and writes more directly expensive, while LSM-trees make writes cheaper upfront and shift some complexity to reads and background maintenance. Range scans are often friendlier in B-tree-based systems because the data is already laid out in order. High-ingest workloads often favour LSM designs because append-heavy writes map better to storage devices.
That summary is useful but incomplete. Real systems add caches, filters, compression, and compaction policies that can move the boundary considerably.
Operational tradeoffs
B-tree systems often need care around vacuuming, fragmentation, and index bloat. LSM systems need care around compaction tuning, write amplification, and read amplification. Both can perform badly when configured against the wrong workload.
This is why storage-engine choice matters. A database built on an LSM-tree may excel at sustained ingestion and replication logs, while a B-tree engine may be easier for transactional applications that need consistent point reads and range queries.
Which one to prefer
Prefer the structure that matches the workload you actually have. If reads are diverse, ordered, and latency-sensitive, B-trees are often the safer default. If writes dominate and sequential append behaviour is valuable, an LSM-tree design can be a better fit.
Neither structure is universally superior. They embody different decisions about where the system should spend effort: in the foreground on writes, or in the background on maintenance and more complex reads.