PostgreSQL backup and point-in-time recovery: what it protects and why it is harder than it looks
A production PostgreSQL cluster that holds data it cannot lose needs a recovery limit you can state in advance. A single nightly dump cannot provide one. Every change made after the last dump is gone if the server fails, and the loss window grows or shrinks with the dump schedule, not with the data's value. Point-in-time recovery closes that gap. It restores a base backup, then replays archived write-ahead log (WAL) files up to a chosen moment. The recovery point you can reach is only as good as the WAL you archived, so the first decision is how far back and how finely you need to recover, and whether your archive can deliver that.
The design depends on three things working together: WAL archiving, retention and restore procedures. Archiving is configured through PostgreSQL settings such as archive_mode and archive_command, which decide where each completed WAL segment goes. Retention must keep every base backup you might restore from, plus all WAL generated since the oldest of those backups. Incremental backups add a dependency: pg_basebackup can take them, and pg_combinebackup reconstructs a full data directory from the chain at restore time. A restore that uses a chain is only as reliable as the chain itself, so the procedure must name the exact backup set, the tool versions and the order of steps.
Teams find this harder than expected for three recurring reasons. First, archives stop without anyone noticing. A failing archive_command, a full archive volume or changed credentials can leave WAL piling up on the primary while backups still appear to run. Monitor archiver status and alert on failures and on the age of the newest archived segment. Second, restores are rarely rehearsed, so the first real restore becomes the test. Third, backups must match the server. Minor releases arrive at least every three months and do not change the storage format, but the restore binaries and tooling must still fit the major version in use. Confirm that your current major version is supported: version 14 is supported until November 12, 2026, according to the PostgreSQL versioning policy.
Backup does not replace high availability. Hot standbys and streaming replication keep a second copy current, which helps with hardware failure and planned switchover. But replication copies destructive changes too. A dropped table or a bad bulk update reaches every standby within moments. PostgreSQL also does not detect a failed primary or promote a standby on its own, so automatic failover needs an external tool. Plan both: replicas for availability, and tested backups with archived WAL for recovery from logical damage. The work is open source tooling plus your own storage, networks and operations staff. Ask any partner to define retention, storage capacity, restore test frequency and monitoring ownership in writing before the first backup runs.
Which PostgreSQL pieces make point-in-time recovery work
Point-in-time recovery depends on six components working together: a base backup, the WAL archive written while the server runs, the configuration that enables archiving, optional incremental backups, the storage that holds everything, and a restore environment that replays it. Each part can be correct on its own and still fail during a restore, so confirm all six in your environment before you set recovery objectives.
Base backup with pg_basebackup
pg_basebackup copies the full data directory of a running cluster. It is the starting point for every point-in-time recovery, because WAL replay begins from this copy and cannot repair a base backup that is incomplete or inconsistent. Confirm how often base backups run, where they are written, and whether they include the WAL needed to reach a consistent state (the -X option controls this). Confirm that a failed backup job raises an alert instead of exiting silently.
Server configuration for continuous archiving
Continuous archiving is switched on in postgresql.conf. The archive_mode setting must be enabled, and wal_level must be set high enough to write the information recovery needs. Changing archive_mode requires a server restart, so plan the change in a maintenance window. Confirm these settings on every node that could become primary, because a standby promoted without them will not archive.
Archived WAL files and archive_command
The archive_command setting runs for each completed WAL segment and copies it to the archive. PostgreSQL reads the command's return code to decide whether the copy succeeded, and a command that keeps failing causes WAL to accumulate on the primary's disk. The command should refuse to overwrite an existing file and should fail visibly. Confirm disk headroom for queued WAL, alerting on archive failures, and that the archive is continuous from the base backup onward.
Incremental backups with pg_combinebackup
Incremental backups store only the blocks changed since an earlier backup, which can shorten backup windows and reduce transfer volume. pg_combinebackup rebuilds a full data directory from the chain of backups before recovery can use it. Each incremental depends on every backup before it, so losing one link breaks the chain. Confirm that WAL summarization is enabled on the source server, that the chain is tracked and retained as a unit, and that the restore environment has disk space for the rebuilt copy.
Archive storage target
The archive target holds base backups, WAL segments and any incremental chains. It should sit outside the failure domain of the primary, so that a host, disk or account failure does not remove both the database and its recovery copies. Confirm the retention period, encryption at rest, access controls that keep backup credentials away from routine database administration, and whether immutability or object lock features are available on your storage platform. Ask for evidence of test restores from this target.
Restore environment and restore_command
Recovery runs on a separate server or cluster that uses a restore_command to fetch archived WAL files back into the recovery process. The restore environment must run a PostgreSQL version compatible with the backups, which in practice means the same major version as the source. Confirm that the restore_command can reach the archive from that network, that the server has the disk and memory for replay, and that the recovery target (time, transaction or named restore point) is written down before each restore begins.
Choosing full, incremental and archive-based PostgreSQL backup designs
This table compares four PostgreSQL backup designs and the operational cost each adds, including storage growth, restore steps, archive dependence and combine time. Read each row against your recovery point and restore time targets, then confirm the figures in your own restore tests. The main takeaway is that only designs with archived WAL can recover to a chosen moment, and logical dumps alone cannot.
| Design | When it fits | Operational cost | What to confirm |
|---|---|---|---|
| Full base backups only | Small databases where the last backup is an acceptable recovery point | Each run copies the whole cluster, so storage grows fastest. Restore is one step to the backup moment. | Backup window, storage growth per run and restore time in your own test |
| Base backups plus WAL archiving | Systems that must recover to a chosen moment after a bad change or deletion | Needs continuous WAL shipping. Restore replays archived WAL, so an archive gap blocks recovery. | Archive gap alerting, daily WAL volume and replay time to a target moment |
| Incremental base backups plus archiving | Large clusters where full copies are costly to store or transfer | Restore combines the full backup and incrementals before replay. A broken chain or long combine time adds delay. | Combine time at your data size, chain retention rules and tool support on your PostgreSQL version |
| Logical dumps for selected databases | Single databases, schema moves, version-portable copies or selective restores | Restore rebuilds data and indexes, which is slower at scale. No point-in-time recovery. | Restore duration at your size and consistency when databases are dumped at different times |
| Physical plus logical combined | Full cluster recovery plus a portable copy of key databases | Two schedules to run, monitor and restore-test. Storage use grows with both copies. | Which databases need the logical copy and how often each copy is restore-tested |
| Point-in-time recovery requirement | Any design that must recover to a moment between backups | Requires a base backup and archived WAL. Logical dumps alone do not provide it. | Archive location, archive retention and whether the recovery point objective is met in tests |
How to set up PostgreSQL backup and point-in-time recovery step by step
This sequence takes a PostgreSQL cluster from an unprotected primary to a tested setup in which a base backup and archived WAL can restore the database to a chosen moment. Each step names the artifact it produces and the check that closes it.
Confirm the PostgreSQL version and cluster layout
The platform team records the exact major and minor version of every node, whether standbys exist, where the data directory and WAL files sit, and which storage and network paths the backup job will use. Confirm that the major version is still within the supported range in the PostgreSQL versioning policy before building around it. The artifact is a cluster inventory. The step closes when the team can name each node, its version, its data directory and its disk, and when a reviewer signs off that the inventory matches the running systems.
Choose and secure an archive location separate from the primary
Select a target for archived WAL and base backups that does not share a failure domain with the primary's disks, such as separate storage in another account, site or administrative boundary, as your recovery requirements dictate. Give only the backup service identity write access, enable encryption at rest and in transit, and turn on access logging. The artifact is an archive location with a written access policy. The step closes when a test file written by the backup identity reads back correctly and a delete attempt from the database host's service account is denied.
Enable WAL archiving with archive_command
Set archive_mode and archive_command in the server configuration. Changing archive_mode requires a restart, so schedule that change with the owners of the database. The archive_command must return success only after the segment is durably stored in the archive, because PostgreSQL recycles a segment once the command succeeds. The artifact is the saved configuration with a documented archive command. The step closes when a manual switch with pg_switch_wal() produces a new WAL file in the archive and pg_stat_archiver shows the archived count increasing.
Take the first base backup with pg_basebackup and record its label
Run pg_basebackup against the primary or a standby with an explicit backup label, and write the output to the archive location or a staging path that is then copied there. Record the label, start time, completion time, the WAL start and stop positions, and the storage path in a backup register. The artifact is a base backup with a manifest and a register entry. The step closes when the backup completes without error, pg_verifybackup reports the backup as valid, and the register entry matches the backup_label file inside the backup.
Configure retention for base backups and WAL
Decide how many base backups to keep and how far back WAL must be retained, so that every retained base backup has continuous WAL from its start position to the latest archived segment. Implement the rule in your backup tooling or scripts, and make sure WAL needed by the oldest retained base backup is never removed. The artifact is a written retention policy with the approval owner named. The step closes when a dry run lists the files that would be deleted and confirms the oldest retained base backup still has an unbroken WAL chain to the present.
Set up monitoring for archive lag and failed archive commands
Alert on increases in the failed count and last failure time in pg_stat_archiver, on the time since the last successful archive, and on growth of the WAL directory on the primary. Route alerts to the on-call owner and attach a short runbook covering the first checks. Thresholds should come from your recovery point objective, so set them with the people who own that objective. The artifact is the alert rules and runbook. The step closes when a deliberately failing archive command in a test environment triggers the alert within the expected window and the runbook steps reach a fix.
Add incremental backups after a full chain restores once
Only after a full base backup and its chain restore successfully on a test host should the team add incremental backups with pg_basebackup's incremental option. Restores of incremental backups run pg_combinebackup first to rebuild a full data directory, so the runbook must include that step. Confirm that your PostgreSQL version and tooling support the options you plan to use. The artifact is an incremental schedule and a documented restore chain. The step closes when a restore from a full backup plus its incrementals passes the same checks as a restore from a full backup alone.
Run a first point-in-time restore to a test host
Restore the latest base backup to an isolated host, set restore_command so the server fetches WAL from the archive, and set recovery_target_time to a moment before a known change made in a controlled test. Start the server, let recovery finish, and confirm it stops at the target. The artifact is a restore record with the target time, timings and results. The step closes when a marker row or known data set shows the state at the target time, no later changes are present, and the elapsed restore time is recorded for later comparison with recovery time objectives.
Setting recovery point and recovery time objectives for PostgreSQL
Set the recovery point objective (RPO) and recovery time objective (RTO) for each database or service before any backup design starts, because both values determine how the rest of the system is built. The RPO is the maximum amount of committed data you accept losing. In a PostgreSQL design it maps mainly to how often write-ahead log (WAL) segments are archived. Between archive events, committed transactions exist only on the primary, so a longer archive interval or a delayed archive command means a larger possible loss. Ask the team to confirm the archive_timeout and archive_command settings that will apply, and to set up monitoring that alerts when the archive falls behind or when archiving fails. An RPO that nobody watches is not being met.
The RTO is the maximum time from the decision to restore until the service accepts traffic again. In PostgreSQL it depends on four things: the size of the base backup that must be copied back, the volume of WAL that must be replayed after that backup to reach the target point, the hardware the restore runs on, and the people who run the procedure. Replay time grows with the time elapsed since the last base backup, so the base backup schedule is part of the RTO decision. Restore hardware includes storage throughput and the network path from the backup repository. Staffing matters because a restore run by one person at night, following an out-of-date runbook, takes longer than a rehearsed procedure with named roles.
Write both objectives for every database or service in a short register that names the owner, the data set, the RPO, the RTO and the date each value was approved. Shared clusters often hide different needs, so one ledger entry per logical database is safer than a single figure for the cluster. Ask the business owners to approve these values in writing before design begins. Their approval should cover the cost trade-off they accept: a tighter RPO usually means more frequent archiving, more monitoring and more storage, while a tighter RTO usually means more frequent base backups, faster restore hardware and a standby or rehearsed procedure. Record which values were set by the organization and which were proposed by the implementation team, so that the approval trail is clear during an audit or incident review.
Treat the approved objectives as targets, not as measured results. The figures come from your organization, and an implementation partner or vendor cannot set them for you. The achieved values must come from restore tests run against production-sized data on production-like hardware. Measure the time from the start of the restore to a verified, accepting database, and measure the newest transaction present after recovery to determine the actual data loss. Run these tests on a schedule, record the results against each target, and treat any gap as a design defect to fix or a target to renegotiate with the business owner. Confirm with your own environment and your backup tool's documentation how the restore steps and timings should be recorded.
How PostgreSQL backup and point-in-time recovery differs by deployment model
A single-node cluster has one primary, so base backups and archived WAL files come from the same machine that serves production traffic unless that work is moved elsewhere. The design question is how to keep backups outside the database host's failure domain while keeping the restore path short enough to meet your recovery objectives.
- Storage location: Send base backups and WAL archives to a separate target, such as object storage or a backup host in another failure domain. Confirm retention, access controls and encryption with your storage team.
- Where backups run: With no standby, base backups run on the primary. Expect added I/O during the backup and schedule or throttle it, then measure the effect on your workload.
- Restore isolation: Restore to a separate host so a failed or test restore cannot damage the only copy of live data.
- Failure visibility: Confirm that a failed archive command or a gap in WAL delivery raises an alert, because there is no standby to fall back on.
Before go-live, run a full restore on a spare host and time it against your recovery time objective, since a single-node design has no second node to hide a slow or broken restore.
With hot standbys, base backups can run from a standby, which moves backup I/O off the primary. PostgreSQL does not detect a primary failure or promote a standby on its own, so the external failover manager and the backup design must agree on which node is the active source of archives after a switchover.
- Backup source: Running backups from a standby reduces load on the primary, but confirm that the standby's replay lag stays within the recovery point you have agreed to and that the backup method you chose is supported in your configuration.
- Storage and timelines: Archive WAL from whichever node is primary at the time, and make sure timeline history files reach the archive too, so a restore can follow the path through each promotion.
- Restore isolation: Restore into a new cluster. Never reattach a restored copy to the production replication topology, because a promoted node can be mistaken for a clean restore target.
- Post-failover checks: Confirm which node takes backups after a failover, whether the failover manager runs any backup-related hooks, and that archiving was tested on the new primary.
Test a failover and a backup in the same exercise, since archiving that works on the old primary can stop silently after promotion.
On Kubernetes, PostgreSQL runs in pods with persistent volumes, and backup behavior depends on the operator managing the cluster, the storage class and the object storage target. Confirm each operator capability with the operator project for your version before you rely on it, since features differ between projects and releases.
- Storage location: Volumes inside the cluster do not protect against loss of that cluster. Place base backups and WAL in storage outside the cluster's failure domain and verify network access from the cluster to that target.
- Where backups run: Ask whether the operator takes base backups from a replica or only from the primary, and what I/O impact to expect on the primary during the backup.
- Restore isolation: Restore into a separate namespace or cluster with its own volumes and credentials, so restore tests cannot reach production secrets, service accounts or persistent volumes.
- Recovery behavior: Confirm whether point-in-time recovery to a named time is supported, how timeline changes after failover are handled, and whether a restore can run without cluster-admin rights in production.
Record the operator project's documented answers for your version in your runbook, and re-check them after each operator upgrade.
On air-gapped or tightly segmented networks, WAL and base backups usually cannot reach a cloud object store, so the storage target, the transfer path and media handling become part of the design. The team also has to plan how restore tooling, documentation and keys reach the enclosed network before an incident, not during one.
- Storage location: Use on-premises object storage, a backup appliance or a dedicated backup host in a separate room or site. Confirm replication to a second site and the retention limits of the chosen storage.
- Where backups run: Backups usually run from the primary or a standby inside the same network. Confirm that backup I/O fits the maintenance windows approved for the environment.
- Restore isolation: Run restores on a segmented host with separate credentials and no write path to production storage. Verify that restore hosts are unable to reach production databases.
- Transfer and keys: Confirm how WAL moves across any approved transfer mechanism, where backup encryption keys are held and escrowed, which PostgreSQL and tool versions must be carried in, and how restore tests are logged as evidence.
Confirm the transfer path and key handling with your security team before the design is final, since they set the practical limit on your recovery point.
What drives PostgreSQL backup and recovery effort and cost
This table lists the main factors that change how much work and spend a PostgreSQL backup and point-in-time recovery program needs, with how each factor raises effort and how to keep it down. Read each row against your own environment, then use the same drivers to check any quote you receive.
| Driver | Why it changes effort or cost | How to keep it down |
|---|---|---|
| Database size and write volume | Size sets the base backup duration and storage footprint, while write volume sets how much WAL is generated and archived between base backups. Both grow storage, network transfer and restore time. | Schedule base backups off-peak, use incremental backups where pg_combinebackup fits your restore process, and measure WAL volume before sizing archive storage. |
| Number of clusters and environments | Each cluster needs its own archive stream, schedules, monitoring and restore procedure, and each non-production copy adds backup work that is often overlooked. | Standardize backup configuration across clusters and environments, and decide which non-production systems really need point-in-time recovery. |
| Retention and legal hold requirements | Longer retention multiplies storage and makes restore catalogs larger. Legal holds can force data to be kept outside the normal expiry cycle and need a documented process to release them. | Limit retention to what the recovery and regulatory objectives require, and confirm with legal counsel how holds are recorded, applied and released. |
| Recovery time objective | A short restore target usually needs pre-staged hardware, tested runbooks, faster storage and more frequent restore rehearsals, which all add cost. | Set the objective per system from business impact, then size restore infrastructure to meet only the objectives that are truly tight. |
| Recovery point objective | A tight point objective requires continuous WAL archiving with monitored archive delivery, so archive failures must be detected and alerted quickly. | Set the point objective per system, and monitor archive lag and failures so the target is backed by alerting rather than assumption. |
| Integration with existing backup tooling and storage | Connecting to an enterprise backup product, object storage, tape or a secrets manager adds configuration, credential handling and vendor-specific testing. | Confirm early which tools and storage tiers are mandatory, and reuse existing storage and monitoring rather than building parallel systems. |
| Compliance evidence needs | Assessors expect records of backup schedules, retention settings, encryption, access controls and restore test results. Producing this evidence is ongoing work, not a one-time export. | Generate evidence from configuration and restore test logs on a fixed schedule, and agree the evidence list with your assessor before the build starts. |
| Number of people trained to restore | If only one person can run a point-in-time recovery, restore testing and incident response depend on that person, and gaps appear during absence or turnover. | Train at least two staff to run restores from the runbook, and rehearse them on a schedule so the procedure stays current. |
Running PostgreSQL backups after go-live: monitoring, retention and version changes
After go-live, the backup set stays restorable only if someone watches it. The recurring work covers four areas: alerting on archive failures and archive lag, reviewing the age of the most recent base backup, pruning WAL and base backups according to the retention policy, and keeping the restore runbook current. Alerts should fire when archive_command fails, when pg_stat_archiver reports repeated failures, and when the newest archived WAL segment falls behind the primary. A failed archive does not stop the database, so without an alert the gap can grow for days before anyone notices it.
Retention pruning needs care because WAL segments are only useful in relation to a base backup. Before deleting an old base backup, confirm that the oldest one you keep still has every archived WAL file needed to reach any point inside your recovery window. Whether your backup tool handles this automatically, or whether your own scripts must, is a question to settle before go-live and test in a staging environment. The runbook should record the retention period, the storage locations, the credentials needed to read them, and the named people who can approve a restore. Review it after every change to hosts, storage or tooling, because a runbook that points at last year's paths fails when it is needed most.
Minor releases arrive at least once every three months, according to the PostgreSQL versioning policy. They never change the internal storage format, so applying one means replacing the executables and restarting the server, and the existing base backups and WAL remain usable. That does not remove the need for a restore test. Restores run on the new binaries, so a test restore after each minor update confirms that the tooling, library paths and recovery settings still work. Schedule the test as part of the patch window and record the result in the same change record.
Major upgrades change the restore target itself. A major version is a different release from the one that wrote the backups, and PostgreSQL's upgrade options (pg_dumpall with restore, pg_upgrade, or logical replication) each affect how you recover afterward. Plan a new base backup on the upgraded version as soon as the cutover is complete, and confirm with your backup tool and the PostgreSQL upgrading documentation whether older backups can still be restored to their original release. PostgreSQL 14 is supported until November 12, 2026, so restores should be planned against a supported release such as 15 through 18, with the end-of-life date for each version added to the upgrade calendar.
Protecting PostgreSQL backups: encryption, access and secrets
Backups of a PostgreSQL cluster hold complete copies of its data, including base backups and the WAL files that make point-in-time recovery possible. The controls below keep those copies confidential, tamper-resistant and available only to the people and accounts that need them, and each should be checked in your environment before the first archive is written.
Encrypt archives in transit and at rest
Base backups and archived WAL files should be encrypted before they leave the primary host, and every transfer to object storage or a backup server should use TLS. Decide whether encryption happens in the backup tool, in the storage layer, or both, and confirm which key service holds the keys. Check whether an archive can be restored with only the restore account and its key, because a lost or rotated key can make every archive written under it unreadable.
Separate writer and restore accounts
The account that runs archive_command and the scheduled base backup needs only permission to write new objects to the archive location. The account that restores should be used during restore tests and actual recoveries, and its credentials should be stored apart from the writer's credentials. Confirm that neither account can read or delete objects it does not need, and run a restore using the restore account alone to verify that the separation does not block recovery.
Keep backup credentials apart from DBA roles
The backup role should not be a superuser, and it should not be the personal login of a database administrator. Replication connections for pg_basebackup and WAL streaming depend on the REPLICATION attribute and on pg_hba.conf rules, so grant only what your PostgreSQL version requires and review those grants against the role and authentication documentation for that version. A separate role lets you rotate or revoke backup access without touching administrative access to the cluster.
Protect the archive from the primary host
If the primary host is compromised, an attacker holding its credentials could delete or overwrite the archive that would be used to recover it. Store archives in a location the primary cannot delete from, such as storage with write-once retention locks or a separate account with no delete rights, and confirm with your storage provider how object locking is implemented. Test the control by attempting a deletion from the writer account and recording that it fails.
Handle storage keys and passwords as secrets
Storage access keys, encryption keys and database passwords should not appear in postgresql.conf, recovery configuration files, scripts or shell history. Keep them in a secrets manager or in a file with tight ownership and permissions, and rotate them on a recorded schedule. For database passwords, PostgreSQL 18 deprecates MD5 password authentication in favor of SCRAM, so the backup role should authenticate with SCRAM as well.
Apply source data classification to backups
A backup is a full copy of the source database, so it carries the classification, retention and access rules of that database. Record which data classes the cluster holds, then confirm that the archive location meets the same residency, encryption and access requirements, and that the staff who can read backups are approved for the source data. Set backup retention and deletion periods to match those rules, and check them against any legal hold that applies to the data.
How to prove PostgreSQL backup and point-in-time recovery works
A backup is only proven when a restore has been run, timed and checked against the data the business expects back. For a PostgreSQL cluster, the test program should restore the latest base backup to an isolated host, replay archived WAL to a chosen target time, and then confirm the result. Ask the team that owns the cluster to name the target host, the isolation controls around it (no route to production clients, no shared credentials, no write path back to primary storage) and the person who signs off each run. Define what "correct" means before the first run. Agree a short list of tables whose row counts and checksums will be compared against an independent source, such as a read-only copy taken at the target time or a deterministic query over immutable rows. Choose tables that matter to the business, not only the largest ones. Add application smoke tests that log in through the same authentication path clients use, read a known record, write to a scratch table and confirm the write is visible. Run these tests with the application team, because they know which flows matter. Record the exact recovery target (a timestamp or named restore point) so that every run can be repeated and compared. Test the failure cases on purpose. A passing restore proves little if the process only works on a clean archive. Three failures deserve a scheduled test. First, remove or hide one WAL segment in the middle of the replay range and confirm that recovery stops at the gap, does not silently continue, and raises an alert. Second, corrupt a copy of the base backup (for example, by altering one data file in a disposable copy) and confirm that restore or verification fails before the host is presented as recovered. Third, stop the archive destination for a period and confirm that the primary reports archiving failures, that alerts fire, and that the team can see how far the archive lags. Each test should end with a documented stop condition and a named alert, not an operator guess. Record the numbers and compare them to the objectives. For every run, log the time to restore (from the decision to recover until the agreed tables and smoke tests pass), the data loss achieved (the gap between the recovery target and the last committed transaction the business expected to keep) and any manual steps required. Compare these figures with the recovery time objective and recovery point objective that the business has approved. If a run misses an objective, treat it as a finding with an owner and a retest date. Ask for these records in a standard format so that auditors and internal risk teams can see the trend across runs. Schedule the tests and trigger them after change. Regular restore tests should run on a fixed calendar that the owner has agreed in writing, and the failure-case tests should run less often but still on schedule. Add an extra run after significant changes, including a PostgreSQL minor or major upgrade, a change to the archive storage or its credentials, a new base backup method (for example, incremental backups reconstructed with pg_combinebackup), changes to the replication topology or a schema change that alters the agreed tables. Confirm with the vendor and your own environment which tool versions and retention settings each test run uses, and keep those versions in the test record.
Can our team set up PostgreSQL point-in-time recovery alone, and what does outside help cost?
Does our in-house team have the skills to build PostgreSQL point-in-time recovery?
Yes, if your team already runs PostgreSQL in production and has someone comfortable with write-ahead logging, file system layout and backup scheduling. Point-in-time recovery combines a base backup with archived WAL files, so the work is mostly configuration, scripting and testing rather than new architecture.
Skills that are often missing:
- Writing and monitoring archive commands, including alerts for archive failures
- Administering encrypted archive storage and retention rules
- Rehearsing a full restore to a chosen point in time and documenting the result
- Writing runbooks that someone other than the author can follow at night
If no one on staff has performed a point-in-time restore from start to finish, ask an outside team to review the design or run the first restore test with your engineers.
How long does a PostgreSQL point-in-time recovery project take?
The duration depends on the agreed scope, so this page does not give a number. The main drivers are how many clusters are covered, database size and change rate, the archive storage target, how much of the existing backup process must be replaced, and how many restore tests you want documented.
Approval cycles for access, storage and change windows often take longer than the technical work, so account for them early. Ask for the timeline in the written scope, including the phases, the environments involved, and the points where your team must provide input or sign off.
What does our infrastructure and staff need to support PostgreSQL backups?
The work runs inside your own cloud accounts, data centers or air-gapped networks, so your infrastructure must provide the pieces the design depends on. Confirm these before scoping:
- Archive storage with durability, access control and encryption key management
- Network paths from database hosts to the archive location
- Time synchronization across database and backup hosts, so recovery targets are reliable
- A staging environment where restore tests can run without touching production
- Monitoring that alerts when archiving or base backups fail
On the staff side, you need a named database owner, a security reviewer for key and access decisions, and application owners who agree on how much data loss is acceptable for each system.
Should PostgreSQL backups run from a standby server instead of the primary?
Often yes, when the main goal is to reduce load on the primary, but it is a design decision with trade-offs. PostgreSQL supports hot standby servers and both synchronous and asynchronous replication, so a healthy standby can carry some backup work.
The trade-offs to evaluate:
- A lagging or rebuilt standby changes which backups and archives are usable
- Failover tooling must know where backups run, so the setup does not break after a switchover
- Backup jobs must be tested against the standby's actual replay state, not assumed
Decide after reviewing your replication design and your recovery targets. Test the configuration on the PostgreSQL version you run, and confirm its documented behavior before going to production.
What does a fixed-scope PostgreSQL backup engagement include?
A fixed-scope engagement lists its deliverables, timelines and responsibilities in writing before work starts. For backup and point-in-time recovery, the written scope typically covers:
- Review of current backups and the recovery objectives your business has set
- A design document covering base backups, WAL archiving, retention and any incremental backups
- Configuration on the clusters named in the scope, within your infrastructure
- Archive storage setup and access controls
- Monitoring and alerting for backup and archive health
- Restore tests, with results recorded
- Runbooks and handover training for your staff
Confirm the exact list, exclusions and acceptance criteria in the written scope. Ongoing support, upgrades and testing are available separately as retainers.
What drives the cost of outside help for PostgreSQL backups?
Costs fall into three groups: design and implementation work, testing and documentation, and recurring operation. The first two are typically one-time project effort. Recurring costs include the archive storage you pay your cloud or data center provider for, the staging environment for restore tests, and any retainer you choose for ongoing support.
The main cost drivers are the number of clusters, database size and change rate, how much existing tooling must be replaced, how many restore scenarios must be proven, and how much your staff can take on. DeployOpen does not publish a price list. Ask for a quote built from a written scope that lists each component, who performs it, what is one-time and what recurs, and which costs sit with your providers.
How do we prove that a PostgreSQL restore actually works?
Prove it by restoring on a schedule, into a separate environment, and recording what you checked. A useful test restores a base backup, replays archived WAL to a chosen target time, and then verifies the result against known data.
Elements to include:
- Restores to a specific time, not only to the latest backup
- Row counts, key business queries and application smoke tests
- Timings measured against the recovery objectives you set
- Failure cases, such as a missing WAL segment or an unreachable archive
- A dated record of each test, its outcome and the follow-up items
Test evidence supports your own controls and conversations with auditors. DeployOpen prepares systems, controls and evidence for compliance assessments, but independent auditors and certification bodies issue the audit reports.
How DeployOpen scopes, builds and hands over PostgreSQL backup and recovery
DeployOpen plans, implements, documents and supports self-hosted PostgreSQL inside your own infrastructure, including base backups, WAL archiving and point-in-time recovery. Each engagement starts from recovery objectives agreed in writing, and the restore procedure is proven by tests before the system is handed over.
How we scope
- Engagements are fixed-scope, with the backup targets, retention periods and recovery objectives written down before work starts.
- We confirm which PostgreSQL clusters, databases and storage locations the backup design must cover in your environment.
- The written scope states which restore scenarios are tested, such as full cluster restore and restore to a chosen point in time.
How we build
- We configure base backups and WAL archiving to your agreed storage, with archive settings reviewed against the recovery objectives.
- Incremental backup designs use pg_basebackup with pg_combinebackup at restore time, and we test that chain before relying on it.
- Backup jobs, archive monitoring and alerts for failed or missing WAL segments are set up as part of the build.
How we hand over
- Restore runbooks describe each recovery scenario step by step, including who runs it and which credentials and storage they need.
- Restore test results are recorded, showing the timing and the data checks performed after each test restore.
- Your team receives configuration, schedules and retention settings as documentation, so the design can be audited and maintained.
How we support
- Ongoing support, scheduled restore tests and upgrades are available as a retainer, scoped separately from the build.
- Regular restore tests are the practical check that backups remain usable after PostgreSQL minor updates and storage changes.
- Confirm with us during scoping how backup tooling will be kept compatible with the PostgreSQL major upgrade plan.

