# Full-page writes and torn pages

Why the first change to a page after a checkpoint carries the whole 8 KB page in WAL.

> Canonical URL: https://sudohulk.com/writing/full-page-writes-and-torn-pages
> Type: note · Stream: Tech
> Maturity: evergreen. I would defend this. Revisited at least once.
> Published: 2026-09-22
> Tags: postgresql, databases
> Reading time: 1 min
> Author: Vignesh Kumar A <vignesh@sudohulk.com>
> Licence: CC BY 4.0. Quote freely, cite the canonical URL.

---

A **torn page** is what you get when the operating system writes only part of an 8 KB PostgreSQL page before power is lost: the disk sector size is smaller than the page, so half the page can be new and half old. Replaying a normal WAL record against such a page would corrupt it further, because the record assumes the page looked exactly like it did before the change.

PostgreSQL's answer is the **full-page write** (also called a full-page image, FPI): the first time a page is modified after a checkpoint, the WAL record carries the entire page, not just the delta. On recovery, that copy simply overwrites whatever is on disk, torn or not. Later changes to the same page before the next checkpoint carry only deltas, because the full copy in the log has already made the page's starting state safe.

:::gotcha
This is why WAL volume spikes right after a checkpoint, and why spreading checkpoints out (`checkpoint_completion_target`) or checkpointing less often reduces WAL, at the cost of longer recovery.
:::

`full_page_writes` can be turned off on storage that guarantees atomic page writes. Most people should not.

Related: [[pd_lsn vs record LSN]].
