Skip to main content

Back up PostgreSQL to Filebase

PostgreSQL backups stream cleanly to Filebase via pg_dump piped through the AWS CLI. No intermediate disk needed.

One-off backup

pg_dump --format=custom --compress=9 mydb \
| aws --endpoint https://s3.filebase.io s3 cp - \
s3://my-db-backups/postgres/mydb-$(date +%Y%m%d-%H%M%S).dump

The - source for s3 cp reads from stdin, so the dump streams directly into Filebase without ever hitting local disk.

Restore

aws --endpoint https://s3.filebase.io s3 cp \
s3://my-db-backups/postgres/mydb-20260501-120000.dump - \
| pg_restore --dbname=mydb --clean --if-exists

- as the destination of s3 cp writes to stdout, which pg_restore consumes.

Daily backup with cron

/usr/local/bin/pg-backup.sh
#!/bin/bash
set -euo pipefail

BUCKET="my-db-backups"
DB="mydb"
DATE=$(date +%Y%m%d-%H%M%S)
KEY="postgres/${DB}-${DATE}.dump"

export AWS_ACCESS_KEY_ID="$FILEBASE_KEY"
export AWS_SECRET_ACCESS_KEY="$FILEBASE_SECRET"

pg_dump --format=custom --compress=9 "$DB" \
| aws --endpoint https://s3.filebase.io s3 cp - "s3://${BUCKET}/${KEY}"

# Keep only the last 30 days
aws --endpoint https://s3.filebase.io s3 ls "s3://${BUCKET}/postgres/${DB}-" \
| awk '$1 < strftime("%Y-%m-%d", systime() - 30*86400)' \
| awk '{print $4}' \
| xargs -I {} aws --endpoint https://s3.filebase.io s3 rm "s3://${BUCKET}/postgres/{}"

Schedule with cron:

/etc/cron.d/pg-backup
0 3 * * * postgres /usr/local/bin/pg-backup.sh >> /var/log/pg-backup.log 2>&1

With encryption

Pipe through age for client-side encryption before upload:

pg_dump --format=custom --compress=9 mydb \
| age --recipient $(cat /etc/age.pub) \
| aws --endpoint https://s3.filebase.io s3 cp - \
s3://my-db-backups/postgres/mydb-$(date +%Y%m%d).dump.age

Restore:

aws --endpoint https://s3.filebase.io s3 cp \
s3://my-db-backups/postgres/mydb-20260501.dump.age - \
| age --decrypt --identity /etc/age.key \
| pg_restore --dbname=mydb

Treat /etc/age.key carefully — losing it makes the backups unrecoverable.

Logical vs. physical backups

pg_dump produces logical backups: portable, restorable to a different Postgres major version, but slow on huge databases.

For very large databases (TBs), physical backups with pgBackRest or barman targeting Filebase are dramatically faster — they capture WAL streams continuously and let you do point-in-time recovery. Both tools support S3-compatible repositories with the standard endpoint/region settings.

Why Filebase + Postgres backups

  • Free egress — restoring a 500 GB Postgres backup is bandwidth-free.
  • $0.015/GB — keeping months of daily backups stays cheap.
  • No tier transitions — every backup is immediately available; no Glacier-style restore wait.

What's next