Configure TimescaleDB backup and recovery with pgBackRest for automated PostgreSQL protection

Intermediate 25 min Apr 22, 2026 11 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up pgBackRest with TimescaleDB for automated backups, point-in-time recovery, and database protection. Includes configuration for local and remote repositories, scheduled backups, and comprehensive restore procedures.

Prerequisites

  • TimescaleDB or PostgreSQL 12+ installed
  • Root or sudo access
  • At least 10GB free disk space

What this solves

pgBackRest provides reliable backup and point-in-time recovery for TimescaleDB and PostgreSQL databases. This tutorial configures automated backups with retention policies, compression, and secure remote storage options to protect your time-series data from hardware failures and human errors.

Step-by-step configuration

Update system packages

Start by updating your package manager to ensure you get the latest versions.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install pgBackRest

Install pgBackRest from the official package repositories.

sudo apt install -y pgbackrest
sudo dnf install -y pgbackrest

Create pgBackRest repository directory

Create a dedicated directory for pgBackRest repositories with proper ownership and permissions.

sudo mkdir -p /var/lib/pgbackrest
sudo chown postgres:postgres /var/lib/pgbackrest
sudo chmod 750 /var/lib/pgbackrest

Configure pgBackRest

Create the main pgBackRest configuration file with local repository settings.

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=7
repo1-retention-diff=14
repo1-retention-archive=14
log-level-console=info
log-level-file=debug
log-path=/var/log/pgbackrest
log-timestamp=n
process-max=4
start-fast=y
stop-auto=y
archive-async=y
spool-path=/var/spool/pgbackrest
lock-path=/tmp/pgbackrest

[main]
pg1-path=/var/lib/postgresql/14/main
pg1-port=5432
pg1-socket-path=/var/run/postgresql

Create pgBackRest directories

Set up the required directories for logging and spooling with correct permissions.

sudo mkdir -p /var/log/pgbackrest
sudo mkdir -p /var/spool/pgbackrest
sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /var/spool/pgbackrest
sudo chmod 750 /var/log/pgbackrest
sudo chmod 750 /var/spool/pgbackrest

Configure PostgreSQL for archiving

Update PostgreSQL configuration to enable WAL archiving with pgBackRest.

# Add or modify these settings
wal_level = replica
archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'
max_wal_senders = 3
wal_keep_size = 1024

Set pgBackRest configuration permissions

Secure the pgBackRest configuration file with appropriate ownership.

sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf

Restart PostgreSQL

Restart PostgreSQL to apply the configuration changes.

sudo systemctl restart postgresql
sudo systemctl status postgresql

Initialize pgBackRest stanza

Create and initialize the backup stanza for your TimescaleDB instance.

sudo -u postgres pgbackrest --stanza=main stanza-create

Perform initial full backup

Run your first full backup to establish the baseline for incremental backups.

sudo -u postgres pgbackrest --stanza=main backup --type=full

Configure automated backup scheduling

Create a systemd timer for automated backups with proper service file.

[Unit]
Description=pgBackRest TimescaleDB Backup
Wants=postgresql.service
After=postgresql.service

[Service]
Type=oneshot
User=postgres
Group=postgres
ExecStart=/usr/bin/pgbackrest --stanza=main backup --type=diff
StandardOutput=journal
StandardError=journal

Create backup timer configuration

Set up the systemd timer to run daily differential backups.

[Unit]
Description=Run pgBackRest backup daily
Requires=pgbackrest-backup.service

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target

Enable and start backup timer

Enable the systemd timer to run automated backups.

sudo systemctl daemon-reload
sudo systemctl enable pgbackrest-backup.timer
sudo systemctl start pgbackrest-backup.timer
sudo systemctl status pgbackrest-backup.timer

Configure remote backup repository

Add S3-compatible remote repository

Configure pgBackRest to use a remote repository for off-site backups. This example uses MinIO but works with AWS S3 or any S3-compatible storage.

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=7
repo1-retention-diff=14
repo1-retention-archive=14

Add remote repository configuration

repo2-type=s3 repo2-s3-bucket=timescaledb-backups repo2-s3-endpoint=s3.example.com repo2-s3-key=your-access-key repo2-s3-key-secret=your-secret-key repo2-s3-region=us-east-1 repo2-retention-full=14 repo2-retention-diff=30 repo2-retention-archive=30 repo2-cipher-type=aes-256-cbc repo2-cipher-pass=your-encryption-passphrase log-level-console=info log-level-file=debug log-path=/var/log/pgbackrest log-timestamp=n process-max=4 start-fast=y stop-auto=y archive-async=y spool-path=/var/spool/pgbackrest lock-path=/tmp/pgbackrest [main] pg1-path=/var/lib/postgresql/14/main pg1-port=5432 pg1-socket-path=/var/run/postgresql
Security Note: Store S3 credentials securely. Consider using IAM roles or environment variables instead of storing keys directly in the configuration file.

Test remote repository

Verify the remote repository configuration works correctly.

sudo -u postgres pgbackrest --stanza=main --repo=2 check

Point-in-time recovery procedures

Stop PostgreSQL for recovery

Before performing any recovery operation, stop the PostgreSQL service.

sudo systemctl stop postgresql

Restore to latest backup

Restore your TimescaleDB instance to the most recent backup point.

sudo -u postgres pgbackrest --stanza=main restore

Restore to specific point in time

Restore to a specific timestamp using point-in-time recovery. Replace the timestamp with your desired recovery point.

sudo -u postgres pgbackrest --stanza=main --type=time --target="2024-01-15 14:30:00" restore

Start PostgreSQL after restore

Start PostgreSQL service after the restore operation completes.

sudo systemctl start postgresql
sudo systemctl status postgresql

Advanced backup configuration

Configure backup compression and encryption

Add compression and encryption to your backup configuration for security and storage efficiency.

[global]

Add compression settings

compress-type=lz4 compress-level=3

Add encryption for local repository

repo1-cipher-type=aes-256-cbc repo1-cipher-pass=your-local-encryption-passphrase

Existing configuration continues...

Configure backup verification

Set up automatic backup verification to ensure backup integrity.

[Unit]
Description=pgBackRest Backup Verification
Wants=postgresql.service
After=postgresql.service

[Service]
Type=oneshot
User=postgres
Group=postgres
ExecStart=/usr/bin/pgbackrest --stanza=main check
StandardOutput=journal
StandardError=journal

Create weekly verification timer

Schedule weekly backup verification checks.

[Unit]
Description=Run pgBackRest check weekly
Requires=pgbackrest-check.service

[Timer]
OnCalendar=weekly
Persistent=true
RandomizedDelaySec=600

[Install]
WantedBy=timers.target

Enable verification timer

Enable the weekly backup verification timer.

sudo systemctl daemon-reload
sudo systemctl enable pgbackrest-check.timer
sudo systemctl start pgbackrest-check.timer

Verify your setup

sudo -u postgres pgbackrest --stanza=main info
sudo -u postgres pgbackrest --stanza=main check
sudo systemctl list-timers pgbackrest*
journalctl -u pgbackrest-backup.service -f

Monitor backup status

Create backup monitoring script

Set up a monitoring script to check backup status and send alerts.

#!/bin/bash

Check if latest backup is older than 25 hours

LATEST_BACKUP=$(sudo -u postgres pgbackrest --stanza=main info --output=json | jq -r '.[] | .backup[] | select(.type=="full" or .type=="diff") | .timestamp.stop' | sort | tail -1) CURRENT_TIME=$(date +%s) BACKUP_TIME=$(date -d "$LATEST_BACKUP" +%s) DIFF=$(( (CURRENT_TIME - BACKUP_TIME) / 3600 )) if [ $DIFF -gt 25 ]; then echo "WARNING: Last backup is $DIFF hours old" # Send alert (configure your notification method) logger -t pgbackrest "WARNING: Last backup is $DIFF hours old" exit 1 else echo "OK: Last backup is $DIFF hours old" exit 0 fi

Make monitoring script executable

Set proper permissions for the monitoring script.

sudo chmod +x /usr/local/bin/check-pgbackrest.sh

For advanced monitoring integration, you can link this with Grafana dashboards for TimescaleDB analytics or PostgreSQL monitoring with Prometheus.

Common issues

SymptomCauseFix
Archive command failedIncorrect permissions or pathsCheck /var/log/pgbackrest and verify postgres user has write access
Stanza creation failsPostgreSQL not accessibleVerify pg1-path and socket path in /etc/pgbackrest/pgbackrest.conf
S3 backup failsInvalid credentials or networkTest S3 connection: sudo -u postgres pgbackrest --stanza=main --repo=2 check
Restore hangsInsufficient disk spaceCheck available space: df -h /var/lib/postgresql
Backup takes too longLow process-max settingIncrease process-max in pgbackrest.conf based on CPU cores
Timer not runningService dependencies missingsudo systemctl status pgbackrest-backup.timer and check dependencies

Next steps

Running this in production?

Want this handled for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and performant across environments is the harder part. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle high availability infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.