Walk through what a B+tree index does when a new entry must be placed into a leaf page that is already full. What is a page split, and what does it cost?
answer
- Full leaf → allocate, split ~50/50, relink chain
- Separator key is pushed up to the parent
- Cascade upward; root split adds a level
- Two half-full pages replace one full page
- Right-links let readers pass a page mid-split
basics
~20 sIt allocates a new page, moves roughly half the entries into it, links it into the leaf chain, and pushes a separator key up to the parent. If the parent is also full it splits too, and splitting the root adds a level to the tree.
solid answer
~50 sA B+tree stores entries in sorted order inside fixed-size pages. When an insert targets a full leaf: 1. Allocate a new page. 2. Redistribute — classically about half the entries stay, half move to the new page, so both have room. 3. Place the new entry in whichever half its key belongs to. 4. Fix the sibling links so the leaf chain still runs in key order. 5. Insert a **separator key** plus a pointer to the new page into the parent. If the parent is full, it splits by the same rule, and that can cascade upward. When the root splits, a new root is created above it and the tree grows one level — the only way a B+tree gets taller, which is why growth is uniform and all leaves stay at the same depth. The cost is real: extra pages written and logged, a parent (possibly several) modified, brief exclusive latches on multiple pages, and two half-empty pages where one full page used to be.
code
text · 9 linesbefore
parent: [ ... | 40 -> P7 | ... ]
P7 (full, keys 40..79): 40 41 42 ... 78 79
insert key 55
after
parent: [ ... | 40 -> P7 | 60 -> P9 | ... ]
P7 (keys 40..59): 40 41 ... 55 ... 59 -> next = P9
P9 (keys 60..79): 60 61 ... 79 -> next = old P7.nextgo deeper
Say that a full page is split into two, roughly half the entries move to a new page, and the parent is told about the new page.
Add the separator key posted upward, the relinking of the leaf chain, the possible cascade, and that only a root split increases tree height.
Discuss the cost profile — write amplification into the log and replicas, latch contention on hot regions, density and physical-ordering effects — and the workload patterns that trigger splits repeatedly.
Connect split behaviour to key design and concurrency: where insert traffic lands in the key space determines contention and density, and that is a schema decision rather than an index-tuning knob.
## Setting the scene A B+tree index is a balanced tree of fixed-size pages. **Leaf pages** hold the actual index entries — key value plus a pointer to the row — in ascending key order, and are chained to their neighbours so the whole key range can be walked in order. **Internal pages** hold separator keys and child pointers, and exist only to route a search to the correct leaf. Every leaf sits at the same depth; that invariant is what makes lookup cost predictable. ## Why a split is needed at all Pages are a fixed size. An entry must go into the one leaf whose key range covers it — you cannot put it "somewhere else with room", because then range scans and searches would not find it. So when the correct leaf is full, the structure itself has to change. ## The split, step by step 1. **Locate.** Descend from the root using separator keys to find the target leaf. 2. **Detect the overflow.** The new entry does not fit in the remaining free space of that page. 3. **Allocate.** Take a fresh page from the index's free space or extend the file. 4. **Redistribute.** Choose a split point and move the entries above it into the new page. The textbook choice is the midpoint, giving two roughly half-full pages. 5. **Insert.** Place the new entry into whichever of the two pages its key now belongs to. 6. **Relink.** The leaf level is a linked chain in key order. The original page's next-pointer now points at the new page, and the new page points at what the original used to point at (and, in doubly linked implementations, backwards as well). Getting this right is what keeps ordered range scans correct. 7. **Post to the parent.** The parent must learn that a new child exists and which key range it covers, so a separator key and a child pointer are inserted into it. ## Cascading and tree growth Step 7 is an insert into a page, and that page may itself be full — in which case it splits by the same procedure and posts to *its* parent. In the worst case the split propagates all the way to the root. When the root splits, there is no parent to post to, so a **new root** is created containing one separator and two children. This is the only mechanism by which a B+tree grows taller, and because it happens at the top, every leaf gains a level simultaneously. That is why B+trees are always perfectly height-balanced without any rebalancing algorithm of the kind binary search trees need. Height grows very slowly: with a fanout of several hundred children per internal page, three or four levels index hundreds of millions to billions of rows. ## What a split actually costs - **Write amplification.** One logical insert becomes: the original page rewritten, a new page written, the parent modified — and each of those changes is written to the write-ahead log, shipped to replicas, and captured by backups. On engines that log full page images after a checkpoint, the multiplier is larger still. - **Concurrency.** The split must appear atomic to concurrent readers and writers, so it takes short-lived exclusive latches on the leaf, its new sibling and the parent. Under heavy concurrent insert traffic on the same region of the key space, that becomes a contention point. - **Density.** Two roughly half-full pages replace one full page. The freed space is genuinely reusable — but only for keys that fall in those pages' ranges. If the workload never inserts there again, that space stays unused. - **Ordering.** The new page is allocated wherever free space happens to be, which is usually not physically adjacent to its logical neighbour. Repeated splits therefore erode the correspondence between key order and physical layout. ## Splits are not a defect Splitting is the normal, correct growth mechanism of a B+tree; an index that has never split has never grown. The engineering question is not how to avoid splits but how to avoid *paying for them repeatedly* — which is a question about key ordering and about how much free space pages are built with, not about the split algorithm itself. ## Concurrency implementations, briefly Naively, a split appears to require holding locks all the way down the descent path in case the split cascades. Real implementations avoid that. A widely used family of techniques adds a right-link from each page to its right sibling plus a high key marking the page's upper bound: a reader that arrives at a page which has since split and no longer covers its search key simply follows the right-link to the sibling. That lets a split be performed as a sequence of locally-locked steps while concurrent readers proceed without blocking, and it is the reason B+trees scale to high concurrency at all. ## The signature to remember Half the entries move, a separator goes up, the chain is relinked, and the tree only ever grows at the root.
- How does a B+tree stay balanced without a rebalancing operation like a red-black tree's rotations?Because it only ever grows at the root. A split pushes a separator into the parent; if that cascades to the root, a new root is created above it, which increases the depth of every leaf at once. There is no path that can become longer than another, so the tree is balanced by construction rather than by repair.
- Does a page split make previously cached pointers or open scans incorrect?It must not, and implementations go to some trouble to ensure it. Techniques such as right-links plus a per-page high key let a reader that lands on a page which has since split detect that its key is now beyond that page's range and follow the link to the correct sibling. Ordinary descents are also unaffected, because the parent is updated with the new separator as part of the split.
- Do internal (non-leaf) pages split the same way as leaves?The mechanics are the same — allocate, redistribute, post a separator upward — with one difference: at the leaf level the split key remains present in the leaf, whereas when an internal page splits the middle key is moved up into the parent rather than duplicated, since internal pages only route searches and do not store data entries.
A full ring binder: you add a second binder, move half the pages across, label the spines so the index card at the front says which binder holds which range, and make sure each binder points to the next one.
saying these in an interview costs you the question
- "The tree grows a level whenever a leaf splits" — only a root split adds a level
- "Splitting rebalances the tree by rotating nodes" — B+trees have no rotations; balance comes from growing at the root
- "The new page is allocated next to the old one on disk" — it comes from free space wherever it happens to be, which is how physical ordering erodes
- "A split affects only the leaf page" — the parent is always modified, and the modification can cascade
- "Splits are a bug to be eliminated" — they are the normal growth mechanism; only repeated avoidable splitting is a problem