Inside the 8KB Page: PostgreSQL Page Layout Visualized

Interactive visualization of PostgreSQL's 8KB page: header, line pointers, free space, and tuple data.

Each 8KB page has four key regions: a 24-byte header, line pointers (4 bytes each, growing downward), free space, and tuple data (packed upward from the bottom).

Click Insert Row to watch the opposing growth directions in action. The red × on any tuple marks it dead (sets t_xmax) without reclaiming space, the same as PostgreSQL's MVCC, leaving holes between the live tuples. Hit VACUUM to remove the dead tuples, compact the survivors into one contiguous block, and free their line pointers for reuse. A new Insert Row can then land in the reclaimed space. Click any region or tuple card for byte-level details.

Rows
0
pd_lower
24
pd_upper
8192
Free Space
8168 B
Page Inspector click a region on the map small regions enlarged for clarity · thin bar shows actual proportions
Header 24 B
Free Space 8168 B
0 8192
sql>
Tuple Inspector page_demo (id int, title text, created_at timestamptz, amount numeric)
insert rows to watch the page fill up

What VACUUM does to the page

VACUUM walks the page, drops the dead tuples, and runs PageRepairFragmentation to slide the surviving tuples together so the freed bytes coalesce into one contiguous block of free space. The live tuples move, but they keep their line pointer slot numbers: an index entry points at a tuple by (block, offset), so the slot number has to stay stable even as the tuple's physical offset changes.

A dead tuple's line pointer does not jump straight to free. After the DELETE it is still LP_NORMAL; pruning marks it LP_DEAD; only once VACUUM has cleared the matching index entries does it become LP_UNUSED and available again. The next INSERT fills an LP_UNUSED slot before extending the array, so a low slot number can carry a brand-new row. Trailing unused slots are dropped from the end of the array, pulling pd_lower back down; interior unused slots stay put as gaps waiting to be reused.

Changelog

  • Added VACUUM: remove dead tuples, compact the page, and reuse freed line pointers.
  • Deleted tuples now show as in-place dead space on the page map until reclaimed.
  • First release: interactive 8KB page map with header, line pointers, free space, and tuple data.