← All guides

Backing up Railway Postgres (beyond volume snapshots)

Railway snapshots restore disks, not data. Setting up pg_dump backups for Railway with the TCP proxy, plus a read-only role.

Snapshots vs backups

Railway volume snapshots protect against infrastructure loss and fat-fingered service deletion (if you catch it). They can't be inspected, partially restored, or moved elsewhere. For data incidents you want logical backups too.

pg_dump over the TCP proxy

# DATABASE_PUBLIC_URL from your service variables
pg_dump "$DATABASE_PUBLIC_URL" --format=custom --no-owner \
  --file=railway_$(date +%F).dump

Create a read-only role first (connect as postgres):

CREATE ROLE backup_reader LOGIN PASSWORD '...' NOSUPERUSER;
GRANT CONNECT ON DATABASE railway TO backup_reader;
GRANT USAGE ON SCHEMA public TO backup_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO backup_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO backup_reader;

Then automate + verify

Cron it (GitHub Actions works), encrypt before upload, keep GFS retention, heartbeat a dead-man switch, and restore-test the output. That list is exactly why managed verified backups exist.

Whatever tool made your backup, the only way to know it works is to restore it. Firedrill does that automatically for every backup — or try a one-off free drill on a dump you already have.

A backup you've never restored is a hope, not a backup.

Firedrill restore-tests every backup it takes — on real infrastructure, with the report to prove it.