A heap page with free space takes any new row. A B-tree leaf with free space takes only the keys that sort into its range, which is why an index can stay the same size after VACUUM has emptied most of it.
This is one index on an integer column, scaled down so a leaf holds 9 items where a real 8KB leaf holds 367. The first scenario deletes rows scattered across the whole key order and follows the index through VACUUM, new inserts, and a rebuild. The second deletes one contiguous key range, which is the only case where VACUUM gives pages back, and shows where those pages go. Free play has every statement as a button. Click any page or item for its bt_page_stats or bt_page_items row.
What VACUUM does to the root when it deletes a leaf
Step the second scenario to its first VACUUM and compare the root with the step before. The deleted leaf's item is still there with its key, now leading to the right sibling, and the item that used to lead to that sibling is gone. On PostgreSQL 18.6, deleting the leaf that held 3670 to 7320 from a seven-leaf index turned the root's (2,1) 3670 and (4,1) 7330 into a single (4,1) 3670. The right sibling inherits the deleted page's key range and the left sibling keeps its high key as it was. The rightmost leaf has no right sibling to take its range, so it is never deleted, even when it is empty.
When a deleted page can be reused
A deleted page isn't reusable straight away, because a scan that read the old downlink may still be on its way to it. VACUUM stamps the page with the next transaction ID and recycles it once that ID is in the past for every snapshot. With nothing else running, two VACUUMs back to back leave the page at 0 reusable, and one INSERT in between is enough for the second VACUUM to put it in the free space map. The second scenario runs exactly that sequence. After it, a page split takes the recycled block before the file grows, and a page split is the only thing that ever will.
What is left out
Deduplication and posting lists, the LP_DEAD hints that index scans leave behind, and trees deeper than one level. Leaf density here counts item slots, where pgstatindex counts bytes.