Tuple header (HeapTupleHeader)
Also called: HeapTupleHeaderData, t_hoff, row header
Every heap row begins with a fixed header (HeapTupleHeaderData) of about 23 bytes carrying the MVCC fields xmin/xmax, the row's own location pointer (ctid), and flag words (t_infomask) recording things like "this row has NULLs" or "this row has variable-width columns". t_hoff marks where the header (plus any NULL bitmap) ends and the column data begins.
What this means
Every row starts with a fixed header of about 23 bytes, before any of your data. It carries the MVCC bookkeeping (xmin/xmax, which transactions created and deleted this version), the row's own address, and flag bits noting things like "this row has NULLs." A marker in it, t_hoff, says where the header ends and your columns begin.
Why it matters operationally
The header is fixed per-row overhead, which is why very narrow tables still have a noticeable minimum row size. Its flag bits (HEAP_HASNULL, HEAP_HASVARWIDTH, HEAP_HASEXTERNAL) tell deforming whether to expect a NULL bitmap, padding, or TOAST pointers, driving how the rest of the row is read.