B-Tree
A self-balancing tree data structure used by most relational databases for indexes. Keeps data sorted and allows searches, insertions, and deletions in O(log n).
What is B-Tree?
In short
A B-tree is a self-balancing tree data structure that keeps keys sorted and lets a database find, insert, or delete a row in O(log n) time. It is the structure behind most relational database indexes because each node holds many keys, so even a billion-row table is only 3 or 4 levels deep, meaning a lookup touches just a handful of disk pages.
What a B-tree actually is
A B-tree is a sorted tree where every node can hold many keys instead of just one. A binary search tree splits into two children at each node and gets tall fast. A B-tree splits into hundreds or thousands of children at each node and stays short. That shortness is the whole point, because the height of the tree is how many disk reads it takes to find something.
The B stands for balanced, not binary. All leaf nodes sit at the same depth, and the tree rebalances itself on every insert and delete so it never degenerates into a long chain. This guarantees that search, insert, and delete all stay O(log n) no matter what order the data arrives in.
Each node maps to one disk page or block, usually 4 KB, 8 KB, or 16 KB. Because a page holds many keys, the branching factor (often called the fanout) is large. A fanout of 1000 means a tree only 3 levels deep can index a billion keys. Three page reads to find any row in a billion is why B-trees have dominated databases since the 1970s.
How it works under the hood
Reading is a top-down walk. You start at the root, do a binary search inside the node to pick the right child pointer, follow it to the next node, and repeat until you hit a leaf. Each step is one page read. Within a page the search is in memory and effectively free compared to the disk hit.
Inserting starts the same way: find the leaf where the key belongs and put it there. If the leaf is now full, it splits in half and pushes the middle key up to the parent. If the parent overflows too, it splits as well, and a split can cascade all the way to the root. When the root splits, the tree grows one level taller. Deletes work in reverse, borrowing keys from siblings or merging underfull nodes so no page drops below half full.
Most real databases use a B+ tree, a variant where all the actual data or row pointers live only in the leaf nodes, and internal nodes hold just keys for routing. The leaves are also chained together in a linked list, so once you find the start of a range you can walk sideways through the leaves to read the rest. That is what makes range scans like WHERE created_at BETWEEN x AND y fast, and what powers ORDER BY without a separate sort.
When to use it and the trade-offs
B-trees are the default index for almost every relational workload because they handle both point lookups (find user 42) and range queries (find orders from last week) well, and they keep results in sorted order for free. If you do not know what to index with, a B-tree is the safe answer.
The cost is on writes. Every insert can trigger a page split and rewrite, and random inserts scatter writes across the tree, causing write amplification and fragmentation over time. Workloads with huge sustained write volume, like time-series ingestion or event logging, often do better with an LSM-tree (log-structured merge tree), which batches writes sequentially. RocksDB, Cassandra, and modern InnoDB-alternative engines lean on LSM-trees for exactly this reason.
A B-tree index also only helps when your query filters on a prefix of the indexed columns. An index on (last_name, first_name) speeds up a search by last name, but does nothing for a search by first name alone. And hash indexes beat B-trees for pure equality lookups since they are O(1), but a hash index cannot do ranges or sorting at all, so you give up the B-tree's biggest strength.
A concrete real-world example
When you run CREATE INDEX idx_email ON users(email) in PostgreSQL, it builds a B+ tree keyed on email. A query like SELECT * FROM users WHERE email = 'a@b.com' then walks from the root down to a leaf in 3 or 4 page reads, finds a pointer to the row's location in the table, and fetches it. Without the index, Postgres would scan every row in the table.
Postgres goes a step further and caches the upper levels of the tree in shared memory. For a typical table the root and the level below it stay resident in RAM, so a lookup that logically needs 4 page reads often only hits disk once for the final leaf. That is why a well-indexed lookup stays in the low milliseconds even as the table grows from thousands to billions of rows.
Where it is used in production
PostgreSQL
Its default index type is a B+ tree; every primary key and unique constraint is backed by one.
MySQL InnoDB
Stores the whole table as a clustered B+ tree keyed on the primary key, with secondary indexes as separate B+ trees.
MongoDB
Uses B-tree indexes (via WiredTiger) on the _id field and any user-created index to support fast lookups and range queries.
SQLite
Stores both table rows and indexes as B-trees in a single file, which is what makes it usable as an embedded on-disk store.
Frequently asked questions
- What is the difference between a B-tree and a B+ tree?
- In a B-tree, data or row pointers can live in any node, including internal ones. In a B+ tree, all data lives only in the leaf nodes and internal nodes hold just keys for routing, and the leaves are linked together. The B+ tree wastes a little space on duplicated keys but makes range scans much faster, so almost every real database uses B+ trees and just calls them B-trees out of habit.
- Why are B-trees better than binary search trees for databases?
- A binary search tree has only two children per node, so it gets very tall and each step down the tree is one disk read. A B-tree packs hundreds of keys into a single node that maps to one disk page, so the tree stays only 3 or 4 levels deep even for a billion rows. Fewer levels means fewer disk reads, and disk reads are the slow part.
- Are B-trees stored on disk or in memory?
- Both. Each node is a disk page, so the tree lives on disk and survives restarts. But databases cache the frequently used upper levels in RAM, so the root and the level below it usually stay in memory and only the final leaf read actually hits disk.
- When should I use an LSM-tree instead of a B-tree?
- Use an LSM-tree when you have heavy, sustained write traffic such as logging, metrics, or event ingestion. LSM-trees batch writes sequentially and avoid the random page splits that slow B-trees down on write-heavy loads. The trade-off is slower and more variable reads. For mixed or read-heavy workloads, a B-tree is usually the better default.
- Why does the order of columns in a multi-column index matter?
- A B-tree index sorts rows by the first column, then the second within ties, and so on. A query can only use the index if it filters on a leading prefix of those columns. An index on (last_name, first_name) helps a search by last name, or by last and first name together, but does nothing for a search on first name alone.
Learn B-Tree hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
Related lessons
Lessons that touch on B-Tree as part of a larger topic.
B-Trees
How B-trees work internally, why every database uses them, and what happens when nodes split
foundation · database fundamentals
Database Indexing
B-trees, hash indexes, composite indexes, covering indexes, the single biggest performance lever in any database
foundation · database fundamentals
Index Rebuilding
When your database indexes rot and queries slow to a crawl, how to fix it without taking the system down
foundation · database fundamentals
See also
Related glossary terms you might want to look up next.
Index
A data structure that speeds up database lookups. Like the index at the back of a book that lets you jump to the right page instead of reading every page.
Database
An organized collection of data that can be easily accessed, managed, and updated. The backbone of almost every application.
LSM Tree
Log-Structured Merge Tree: a write-optimized data structure that buffers writes in memory and periodically flushes sorted runs to disk. Used by Cassandra, RocksDB, and LevelDB.
SQL
Structured Query Language for managing relational databases. Tables, rows, columns, and powerful joins to query related data.
NoSQL
Databases that don't use traditional table-based relational models. Includes document stores, key-value, graph, and column-family databases.
ACID
Four guarantees for database transactions: Atomicity (all or nothing), Consistency (valid states only), Isolation (no interference), Durability (changes persist).