Home / Alt manpages / pg_basebackup(1)

  • pg_basebackup(1)
  • User command
  • linux

Create and verify a PostgreSQL base backup with pg_basebackup

You will finish with a complete file-level backup of a running PostgreSQL cluster and a command that checks its manifest. This guide uses the pg_basebackup 16.15 client installed on this machine, from PostgreSQL 16.15 on Ubuntu 24.04. Allow 15 to 30 minutes for a small cluster, or longer if the data directory is large or the server is busy. The backup itself is read-only from the database client's point of view, but it consumes storage, network bandwidth and a replication connection.

This is a cluster backup, not a backup of one database. It includes the cluster's data files, tablespaces and configuration files. Use pg_dump when you need a selective logical backup. The examples below write to a new directory owned by your account. Use sudo only when the chosen destination is not writable by that account.

1. Check the installed client

Confirm that the command is present and record its version. This is an ordinary, read-only check:

$ command -v pg_basebackup
$ pg_basebackup --version
pg_basebackup (PostgreSQL) 16.15

The package suffix may differ on another Ubuntu update, but the important compatibility boundary is the PostgreSQL major version. This client can back up the same major version or an older server, down to PostgreSQL 9.1. WAL streaming requires server 9.3 or newer, and tar format requires server 9.5 or newer.

Checkpoint

Make sure the path printed by command -v is the client you intend to use. Do not mix a PostgreSQL 16 client from one installation with an unrelated set of utilities without checking the deployment first.

2. Prepare the connection and destination

The source server must accept a replication-protocol connection. The connecting role needs the REPLICATION attribute or superuser status, and pg_hba.conf must allow the replication connection. The server also needs enough max_wal_senders for the backup, plus another sender when WAL is streamed.

Choose a destination that does not already contain useful files. With the default plain format, the target directory must be empty if it exists. The command creates a missing directory and its missing parents:

BACKUP_DIR="$HOME/backups/pg-cluster-2026-09-26"
mkdir -p "$HOME/backups"
test ! -e "$BACKUP_DIR" || { printf 'Refusing existing target: %s\n' "$BACKUP_DIR"; exit 1; }

This check avoids an accidental choice of a live data directory or an existing backup. The mkdir command above creates only the parent, not the final target. Do not remove an existing directory just to satisfy the empty-target rule. Choose another name, or archive the old backup using your normal retention process.

3. Take the plain-format backup

Replace the connection values with the server and replication role used by your installation. -P displays approximate progress, -X stream includes required WAL while the files are being copied, and -R writes standby connection settings for a future replica:

$ pg_basebackup \
    --host=DB_HOSTNAME \
    --port=5432 \
    --username=REPLICATION_USER \
    --pgdata="$BACKUP_DIR" \
    --wal-method=stream \
    --progress \
    --write-recovery-conf

Use a .pgpass entry or the normal interactive password prompt rather than putting a password in the command line. The database name in a connection string is ignored because this utility backs up the whole cluster, although a connection string is still useful for other libpq settings.

By default, this client uses a temporary replication slot when the server supports it and WAL streaming is selected without --slot. That helps prevent required WAL from being removed during the backup. It also means a failed or abandoned operation can leave server-side replication state worth checking. A named slot is an operational choice: use --slot=SLOT_NAME only when the slot already exists, or add --create-slot when creating it is deliberate and permitted.

At the start, the command may appear idle while PostgreSQL performs a checkpoint. This is expected. The progress percentage is approximate because the cluster can change while it is being copied, and WAL can add data after the initial estimate.

Checkpoint

A successful run returns status 0 and leaves the target populated. The final files normally include a backup_manifest and a PG_VERSION file. Check without changing anything:

test -s "$BACKUP_DIR/PG_VERSION" && test -s "$BACKUP_DIR/backup_manifest"
printf 'backup directory: %s\n' "$BACKUP_DIR"
du -sh "$BACKUP_DIR"

4. Verify the backup manifest

A successful copy is not enough. Run pg_verifybackup against the directory while the original files are still available:

$ pg_verifybackup "$BACKUP_DIR"
backup successfully verified

The exact diagnostic wording can vary, but the command must return status 0. It checks the files against the manifest and validates the WAL range recorded there. The default manifest checksum is CRC32C, which catches accidental changes quickly. If protection against deliberate tampering matters, choose a SHA algorithm when creating the backup, for example --manifest-checksums=SHA256, and store a trusted copy of the manifest or its verification information separately. A manifest kept beside the backup can be changed with the backup, so it is not by itself an external trust anchor.

If verification fails, preserve the directory for investigation. Do not start a database from it, and do not delete it before recording the error. If the failure is a missing or changed file caused by your own inspection, take a fresh backup instead of trying to edit the backup into compliance.

5. Choose tar output when transport is the priority

Plain format is convenient when the result will become a data directory. Tar format is useful when you want archives or a stream. This example creates compressed tar files in a new directory:

$ pg_basebackup \
    --host=DB_HOSTNAME \
    --username=REPLICATION_USER \
    --pgdata="$HOME/backups/pg-tar-2026-09-26" \
    --format=tar \
    --compress=gzip:6 \
    --wal-method=stream \
    --progress

The main data directory becomes base.tar.gz; additional tablespaces use separate archives. Before starting PostgreSQL from tar output, unpack each archive in the correct location. Tablespace mapping with --tablespace-mapping applies to plain output only, so do not assume it relocates tar contents.

Do not use --no-sync for a production backup. It lets the command return before data is safely written, so a later operating system crash can corrupt the result. Do not use --target=server casually either: it stores the backup on the database server, needs extra server-side privileges, cannot be combined with streamed WAL, and can fill the server's filesystem. The blackhole target is for testing and produces no backup.

6. Handle failures without losing evidence

When the command aborts, the default behaviour removes directories it created while discovering the error. Tablespace directories are not cleaned automatically. Use --no-clean only when you deliberately need the partial files for diagnosis. A partial directory is not a usable backup and must not be promoted as one.

Common errors point to different fixes. An authentication or permission error needs the replication role and pg_hba.conf checked. A full destination needs a new empty target. A WAL error with --wal-method=fetch may mean required WAL was recycled before it could be fetched; streamed WAL avoids that particular delay but needs a second replication connection. If a named slot is missing, create it only through the approved PostgreSQL change process, not by guessing a slot name.

To undo the examples, stop using the verified backup, unmount or stop any service that was deliberately started from it, and remove the backup directory only after its retention and recovery value have been reviewed. Removal is irreversible. The commands in this guide do not alter the source cluster configuration or start a new server.

Done means

  • pg_basebackup --version identified the intended PostgreSQL 16.15 client.
  • The destination was new or empty, and the source connection had replication permission.
  • The backup completed with status 0 and includes PG_VERSION and backup_manifest.
  • pg_verifybackup "$BACKUP_DIR" returned status 0.
  • The verified directory or tar archives are stored on a filesystem with enough space and an agreed retention policy.