Database Backups and Disaster Recovery: A Production Checklist
How to back up your database, test your backups, and recover from disaster. Automated daily backups, point-in-time recovery, and cross-region replication.
RaidFrame Team
January 9, 2026 · 6 min read
TL;DR — A backup that hasn't been tested is not a backup. Automate daily backups with 30-day retention, enable point-in-time recovery, test restores monthly, and keep at least one copy in a different region. On RaidFrame, all of this is automatic for managed databases.
The backup checklist
| Item | Priority | Status |
|---|---|---|
| Automated daily backups | Critical | |
| 30+ day retention | Critical | |
| Point-in-time recovery (PITR) | Critical | |
| Tested restores (monthly) | Critical | |
| Cross-region backup copy | High | |
| Backup encryption | High | |
| Monitoring/alerts on backup failure | High | |
| Documented recovery procedure | Medium | |
| Recovery time objective (RTO) defined | Medium | |
| Recovery point objective (RPO) defined | Medium |
Backup types
Full backups (pg_dump)
A complete copy of your database at a point in time.
# Manual backup
rf db backup main --name before-migration
# List backups
rf db backups mainBACKUPS — main (PostgreSQL 16)
──────────────────────────────
NAME SIZE CREATED STATUS
before-migration 2.3 GB 2026-03-16 14:00 ✓ complete
auto-2026-03-16 2.3 GB 2026-03-16 03:00 ✓ complete
auto-2026-03-15 2.2 GB 2026-03-15 03:00 ✓ complete
auto-2026-03-14 2.2 GB 2026-03-14 03:00 ✓ complete
...Point-in-time recovery (PITR)
Restore to any second within your retention window. Uses continuous WAL (Write-Ahead Log) archiving.
rf db restore main --to "2026-03-16T14:30:00Z"Restoring main to 2026-03-16T14:30:00Z...
WAL replay: ████████████████████ complete
Consistency check: ✓
✓ Restored to 2026-03-16T14:30:00Z
Services restarted with new connectionUse this when:
- Someone accidentally deleted rows (
DELETE FROM users WHERE...without a WHERE clause) - A migration corrupted data
- You need to recover to a specific moment before an incident
Continuous replication
Real-time streaming to a standby database in another region:
rf db replicas add main --region eu-west-1If the primary fails, the replica is promoted automatically. Recovery time: seconds, not hours.
Try RaidFrame free
Deploy your first app in 60 seconds. No credit card required.
Disaster recovery on RaidFrame
What's automatic
| Feature | Starter | Pro | Enterprise |
|---|---|---|---|
| Daily automated backups | ✓ | ✓ | ✓ |
| Backup retention | 7 days | 30 days | 90 days |
| Point-in-time recovery | ✗ | ✓ | ✓ |
| Cross-region backup copy | ✗ | ✗ | ✓ |
| Read replicas | ✗ | ✓ | ✓ |
| Automatic failover | ✗ | ✓ | ✓ |
| Backup encryption (AES-256) | ✓ | ✓ | ✓ |
Test your backups
A backup you've never restored is a hope, not a backup.
# Restore to a test database
rf db restore main --to "2026-03-15T12:00:00Z" --target test-restore
# Verify data integrity
rf db query test-restore "SELECT count(*) FROM users"
rf db query test-restore "SELECT count(*) FROM orders"
# Clean up
rf db delete test-restoreSchedule monthly restore tests:
rf cron add "0 4 1 * *" "rf db restore main --to now-1h --target monthly-test && rf db delete monthly-test" --name backup-testDefine your recovery objectives
| Metric | Definition | Typical Target |
|---|---|---|
| RPO (Recovery Point Objective) | Max acceptable data loss | 1 hour (PITR), 24 hours (daily backups) |
| RTO (Recovery Time Objective) | Max acceptable downtime | 5 minutes (replica failover), 30 minutes (backup restore) |
For most SaaS apps:
- RPO: < 1 hour (use PITR on Pro plan)
- RTO: < 5 minutes (use read replicas with auto-failover)
Self-managed backup patterns
If you're running your own PostgreSQL (on a VPS or container), here's the minimum setup:
Automated pg_dump
#!/bin/bash
# backup.sh — run via cron: 0 3 * * *
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="/backups/mydb_${TIMESTAMP}.sql.gz"
pg_dump -h localhost -U postgres mydb | gzip > "$BACKUP_FILE"
# Upload to remote storage
aws s3 cp "$BACKUP_FILE" s3://my-backups/postgres/
# Delete local backups older than 7 days
find /backups -name "*.sql.gz" -mtime +7 -deleteWAL archiving for PITR
# postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'aws s3 cp %p s3://my-backups/wal/%f'Monitor backup success
Alert if a backup hasn't completed in 24 hours. Missing backups are silent failures — you won't know until you need to restore.
Recovery procedures
Scenario: Accidental data deletion
# 1. Identify when the deletion happened (check logs)
rf logs --service api --search "DELETE" --since 2h
# 2. Restore to point before deletion
rf db restore main --to "2026-03-16T14:25:00Z"
# 3. Verify data is intact
rf db query main "SELECT count(*) FROM users"Scenario: Corrupted migration
# 1. Rollback the deployment
rf deployments rollback
# 2. Restore database to pre-migration state
rf db restore main --backup before-migration
# 3. Fix the migration and try againScenario: Complete region failure
# With read replicas, automatic failover happens in seconds.
# If no replica exists:
# 1. Restore from latest backup in another region
rf db restore main --region eu-west-1
# 2. Update services to use new database
rf deploy --region eu-west-1FAQ
How often should I back up?
Daily automated backups minimum. For critical data, enable PITR (continuous WAL archiving) so you can recover to any point in time.
Where should backups be stored?
In a different region from your primary database. On RaidFrame Enterprise, cross-region backup copies are automatic.
How long should I keep backups?
30 days minimum. 90 days for compliance (SOC 2, HIPAA). Some regulations require longer — check your industry requirements.
Should I back up Redis?
Only if Redis holds persistent data (not just cache). If Redis is a cache, it can be rebuilt from the primary database. If it holds sessions or queues, enable AOF persistence.
How do I know my backups are working?
Monitor backup completion and test restores monthly. On RaidFrame, backup failures trigger alerts automatically.
Related reading
Ship faster with RaidFrame
Auto-scaling compute, managed databases, global CDN, and zero-config CI/CD. Free tier included.