Comparison

Backup Data vs pgBackRest: physical PITR or portable dumps?

pgBackRest gives you point-in-time recovery to the transaction, which no logical dump can match. It also restores only into the same Postgres major version. An honest comparison.

6 min readBackup Data

pgBackRest is the best open-source Postgres backup tool there is. Parallel backup and restore, incremental and differential modes, compression, encryption, delta restore, and — the feature that matters most — point-in-time recovery to any transaction, not to whenever your last dump ran.

If you run Postgres seriously and have not looked at it, look at it. This page is not an argument that it is the wrong tool.

It is an argument that the choice is physical versus logical, and that this distinction, not the feature list, decides which fits your situation. Most comparisons skip it, and it is the only part that really matters.

Physical and logical backups are different things

pgBackRest takes physical backups. It copies the actual data files in PGDATA — the on-disk pages — plus a continuous stream of write-ahead log segments via archive_command. Restoring means putting those files back and replaying WAL up to a chosen moment.

A pg_dump is a logical backup. It reads the database through SQL and writes out the schema and data as instructions to recreate them.

Everything below follows from that one difference:

Physical (pgBackRest)Logical (pg_dump)
Recovery granularityAny transactionWhenever the dump ran
Typical RPOSecondsHours
Restore speed on large DBsFast, parallel file copySlow — replays SQL, rebuilds indexes
Restore target versionSame major version onlyAny version, usually newer too
Restore target platformSame architectureAnything running Postgres
Restore a single tableNo — all or nothingYes
Usable for major upgradesNoYes
Needs filesystem access to PGDATAYesNo
Needs postgresql.conf changes + restartYes — archive_modeNo
Works with managed Postgres (RDS, Supabase, Neon)Usually notYes
Detects logical corruptionNo — copies corrupt pages faithfullyDump fails or produces readable SQL

What pgBackRest is genuinely better at

RPO measured in seconds. WAL archiving means the recovery point is the last archived segment, not the last dump. For a payments database, this difference is the entire argument, and no logical backup schedule closes the gap.

Restore speed at scale. Restoring a 2 TB database from a physical backup is a parallel file copy plus WAL replay. Restoring the same database from a logical dump means executing every INSERT and rebuilding every index — often hours longer. On large databases, physical wins the RTO comfortably.

Recovery to a specific moment. --target-time recovers to just before the bad migration ran. A nightly dump gives you "the night before," which may be fifteen hours of lost work.

Incremental backups of the database itself, at page level, rather than dumping the whole logical content each time.

Barman occupies similar ground with a different operational model; the physical-versus-logical trade-off below applies to it equally.

What the physical model costs you

Version and platform lock. A physical backup restores only into the same Postgres major version, on a compatible architecture. Postgres 15 files do not go into a Postgres 16 server. This means pgBackRest cannot help you upgrade, cannot move you to a different provider, and cannot restore onto a developer's machine running a different version. Logical dumps do all three.

It faithfully backs up corruption. Physical backup copies pages. A corrupted page is backed up as a corrupted page, and if the corruption predates your retention window, every copy has it. A pg_dump reads through the SQL layer, so it usually fails on corrupt data rather than silently preserving it — an unpleasant surprise that is much better received during a backup than during a restore.

Configuration access is mandatory. You need archive_mode = on, an archive_command, a restart, and filesystem access to PGDATA. On RDS, Supabase, Neon or any managed Postgres, you do not have those, which rules pgBackRest out entirely for a large and growing share of deployments.

You run the repository. A host or bucket, with monitoring, capacity planning, and its own backup story. And the common configuration puts that repository in the same cloud account as the database — which protects against a failed disk and not against losing the account.

Operational surface. archive_command failing silently is a classic Postgres incident: WAL accumulates in pg_wal, the disk fills, and the database stops accepting writes. It is well documented and entirely avoidable with monitoring — it is also a failure mode that logical dumps simply do not have.

Side by side

pgBackRestBackup Data
Backup typePhysical + WALLogical dumps
RPOSecondsYour dump interval
PITR to a transactionYesNo
Cross-version restoreNoYes
Works on managed PostgresUsually notYes
Non-Postgres data in the same systemNoYes — files, other engines
DeduplicationPage-level incrementalsContent-defined chunking across everything
EncryptionYes, repo-levelYes, client-side AES-256-GCM
RepositoryYou host itManaged
Config changes to PostgresRequiredNone
CostFree + your infrastructure + your timeFree to 5 GB, then from $12/mo

Which one, honestly

Use pgBackRest if you self-host Postgres, you need an RPO measured in seconds, your database is large enough that logical restore time is a real problem, and you have someone who will own the repository and monitor archive_command. For a serious self-hosted Postgres shop, it is the right answer and nothing here beats it.

Use logical dumps if you are on managed Postgres and cannot configure WAL archiving, you want backups portable across versions and providers, you back up more than just Postgres, or an RPO of hours is genuinely fine for your data — which, for most application databases, it is.

Use both if the database matters enough to warrant it. They cover different failures and the combination is stronger than either:

pgBackRest → repo in your cloud account   → PITR to the second, fast large restores
Logical dump → off-provider snapshots     → survives account loss, restores anywhere

That is not hedging. Physical backups give you granularity; logical backups give you portability and independence. The failure modes they cover barely overlap.

Running the second half

If you already have pgBackRest, adding an independent logical copy is a nightly dump and an upload:

pg_dump --format=custom --no-owner \
  --file=./db-dumps/app.dump \
  "postgresql://postgres@localhost:5432/app_db"
import { BackupClient } from "@lighthouse-web3/baas-js-sdk";

const client = new BackupClient({
  apiKey: process.env.LH_API_KEY,          // write + read scopes only
  workspaceId: process.env.LH_WORKSPACE_ID,
});

const snapshot = await client.backup(["./db-dumps"], {
  description: "nightly logical dump",
  tags: { type: "db-backup", engine: "postgres", env: "prod" },
  encryption: {
    keyfilePath: "/secure/lh.keyfile",
    passphrase: process.env.LH_KEYFILE_PASSPHRASE,
  },
});

Keep the dump filename stable — overwrite app.dump each run — so content-defined chunking ships only the delta. You hold the encryption keys; lose the keyfile and passphrase and the data is unrecoverable, with no server-side reset.

Run the dump from a replica if the extra read load on the primary is a concern. And drill both restore paths, not just the fast one — see the Postgres guide and how to test your backups.

Start with the free tier: backupdata.io has 5 GB free, no card, and the 10-minute quickstart gets you to a first verified snapshot today.

Start with the free tier

5 GB free, no card required. Point your existing dump at Backup Data and get to a first verified snapshot in about ten minutes.

Read the quickstart

Keep reading

Comparison · 7 minBackup Data vs AWS Backup: which fits your stack?Comparison · 8 minBackup Data vs Backblaze B2: a backup system or a cheap bucket?Comparison · 7 minBackup Data vs BorgBackup: who runs the repository?