The one thing to understand first
PostgreSQL never changes a data page on disk without first writing a description of that change to the write-ahead log. That rule — log the intent, durably, before the data — is what makes crash recovery possible: on restart, PostgreSQL replays the WAL and reconstructs every committed change. To really understand durability, replication, and those mysterious post-checkpoint WAL spikes, you need to know what a single WAL <a class="sev1-termlink" href="https://thesev1database.com/glossary/tuple/" title="Tuple">record actually contains.
The fixed header every record carries
Every record begins with an XLogRecord struct, defined in src/include/access/xlogrecord.h:
xl_tot_len — total length of the record in bytes.
xl_xid — the transaction id that generated it.
xl_prev — the LSN of the previous record, chaining the whole log backwards.
xl_info — flag bits, including 4 bits the resource manager uses to say which kind of change this is.
xl_rmid — the resource manager id: heap, btree, transaction, etc.
xl_crc — a CRC-32C checksum over the record, verified on replay so corruption is caught.
After that fixed header come a series of block references (which pages this record touches, via XLogRecordBlockHeader) and the record-specific payload.