← All guides

How to actually test a Postgres backup restores

A restore test is more than pg_restore exiting 0. The checklist: exit code, schema, row counts, index integrity, and query sanity.

Restore into a throwaway database

createdb restore_test
pg_restore --no-owner --no-privileges --jobs=2 -d restore_test backup.dump
echo $?

Exit code 0 is necessary but nowhere near sufficient — pg_restore can 'succeed' while skipping objects, and a dump of the wrong database restores perfectly.

The five checks that matter

1. Exit code — nonzero means read every error line.
2. Schema paritypg_dump --schema-only both sides, diff (or hash) them.
3. Row counts — exact COUNT(*) for small tables, reltuples after ANALYZE within tolerance for big ones.
4. Index integrityCREATE EXTENSION amcheck; SELECT bt_index_check(oid) ... on your biggest indexes.
5. Query sanitySELECT * FROM <table> LIMIT 5 across a sample of tables catches TOAST corruption that counts miss.

Automate it or it stops happening

Manual restore tests happen twice: after you set them up, and after your first data loss. This checklist is literally Firedrill's verification pipeline — we run it on real ephemeral infrastructure for every backup, and the report is your audit evidence.

Whatever tool made your backup, the only way to know it works is to restore it. Firedrill does that automatically for every backup — or try a one-off free drill on a dump you already have.

A backup you've never restored is a hope, not a backup.

Firedrill restore-tests every backup it takes — on real infrastructure, with the report to prove it.