Skip to content

0006: Postgres full backup formats

Date: 2026-10-07 · Status: accepted

Context

The design lists pg_basebackup -X none -Ft for physical backups and pg_dump -Fd -j N (or -Fc) for logical ones, and requires streaming pipelines with no temp files.

Decision

  • Physical: pg_basebackup -D - -Ft -X fetch --checkpoint=fast. With -D - the tar goes to stdout and straight into the pipeline. -X fetch makes every base backup self-contained (restorable even if the change stream has a gap); -X stream cannot write to stdout and -X none needs the stream to restore even the base. Base backups with extra tablespaces are not supported by -D - (none of the current databases use them).
  • Logical: pg_dump -Fc --compress=0 per database to stdout, plus pg_dumpall --globals-only --no-role-passwords. -Fd needs a directory (temp files), so it is not used. Restores use pg_restore reading from stdin.
  • Point-in-time recovery needs physical mode. A logical Postgres target with PITR enabled gets a warning and no streamer.
  • The bootstrap superuser name and the limits recovery checks (max_connections, max_worker_processes, max_wal_senders, max_prepared_transactions, max_locks_per_transaction) are recorded in the manifest and written into the restored configuration.

Consequences

Logical restores are single-threaded per database. Physical backups include WAL from the backup's start to its end (usually small).