Skip to main content

Never Lose Data: Automated Backups and Point-in-Time Recovery on FoundryDB

· 7 min read
FoundryDB Team
Engineering @ FoundryDB

Every managed database service on FoundryDB gets automated backups from the moment it starts running. There is nothing to configure, no S3 bucket to provision, and no cron job to maintain. Backups run daily, are encrypted before they leave the server, and are stored in object storage across a separate availability zone.

But automated daily backups are only half the story. For PostgreSQL, MySQL, and MongoDB, FoundryDB continuously archives write-ahead logs (WAL), binary logs (binlog), or oplogs to enable point-in-time recovery (PITR). This means you can restore to any specific second within a 7-day window, not just to the last daily snapshot.

This post covers how backups work across all engines, how to trigger and restore them, and how to use PITR to recover from the kind of mistakes that daily snapshots cannot fix.

How Backups Work Per Engine

FoundryDB uses the native backup tooling for each database engine. This is intentional. Native tools are the most reliable, best-tested path for each engine, and they integrate with the engine's own consistency guarantees.

EngineBackup toolPITR supportContinuous archiving
PostgreSQLpgBackRestYes, any secondWAL archiving
MySQLmysqldump + binlogYes, any secondBinlog archiving
MongoDBmongodump + oplogYes, any secondOplog archiving
ValkeyRDB snapshotsDaily snapshots onlyAOF (append-only file)
KafkaTopic snapshotsNoN/A

For PostgreSQL, pgBackRest handles full and incremental backups with built-in verification, parallelism, and encryption. WAL segments are archived continuously to S3, so the recovery window extends from the last full backup to the most recent archived WAL segment.

For MySQL, a logical dump captures the schema and data, while binlog archiving captures every write operation between dumps. Restore replays the dump, then applies binlogs up to the target timestamp.

For MongoDB, mongodump captures a consistent snapshot of all collections, and oplog archiving captures the stream of write operations. PITR replays the oplog from the dump point to the target time.

Backup Encryption

All backups are encrypted with AES-256-GCM before leaving the database server. Each backup gets a unique encryption key. Keys rotate automatically every 90 days. Object storage adds a second layer of server-side encryption for defense in depth.

You do not need to configure encryption. It is always on.

# Verify encryption status on any backup
curl -u $API_KEY:$API_SECRET \
https://api.foundrydb.com/managed-services/{id}/backups/{backup_id} \
| jq '{encrypted: .encryption_enabled, algorithm: .encryption_algorithm}'
{"encrypted": true, "algorithm": "AES-256-GCM"}

Triggering an On-Demand Backup

Automated backups run daily, but you can trigger a manual backup at any time. This is useful before a risky schema migration, a bulk data load, or a major application deployment.

curl -u $API_KEY:$API_SECRET -X POST \
https://api.foundrydb.com/managed-services/{id}/backups \
-H "Content-Type: application/json" \
-d '{"backup_type": "manual"}'
{
"id": "bkp_m7x2k9",
"backup_type": "manual",
"status": "in_progress",
"created_at": "2026-04-06T15:30:00Z"
}

Manual backups are retained until you explicitly delete them. Automated backups follow the 7-day retention policy.

Listing Backups

curl -u $API_KEY:$API_SECRET \
https://api.foundrydb.com/managed-services/{id}/backups
{
"backups": [
{
"id": "bkp_abc123",
"backup_type": "automated",
"status": "completed",
"size_bytes": 1073741824,
"created_at": "2026-04-06T02:00:00Z"
},
{
"id": "bkp_m7x2k9",
"backup_type": "manual",
"status": "completed",
"size_bytes": 1073741824,
"created_at": "2026-04-06T15:30:00Z"
}
]
}

Point-in-Time Recovery

Daily backups protect against hardware failure and data corruption. PITR protects against the other kind of disaster: human error. Someone runs DELETE FROM orders without a WHERE clause at 14:32:17. With daily backups, you lose everything since the last snapshot. With PITR, you restore to 14:32:16 and lose nothing.

How PITR Works

PITR combines two pieces: a base backup (the most recent full snapshot) and a continuous stream of change records (WAL segments, binlogs, or oplog entries). To restore to a specific point in time, FoundryDB restores the base backup and then replays the change stream up to the exact target timestamp.

The PITR window on FoundryDB is 7 days. WAL, binlog, and oplog archives are retained for 7 days, so you can restore to any second within that window.

Restoring to a Specific Time

Restoring always creates a new service. Your existing service keeps running undisturbed.

curl -u $API_KEY:$API_SECRET -X POST \
https://api.foundrydb.com/managed-services/{id}/backups/restore \
-H "Content-Type: application/json" \
-d '{
"restore_point": "2026-04-06T14:32:16Z",
"target_service_name": "orders-db-restored",
"plan_name": "tier-2",
"zone": "se-sto1"
}'

The restored service provisions a new VM, restores the base backup, replays the change stream to the specified timestamp, and starts accepting connections. Depending on database size, this takes 5 to 30 minutes.

Restoring from a Specific Backup

If you want to restore from a particular daily or manual backup rather than a point in time:

curl -u $API_KEY:$API_SECRET -X POST \
https://api.foundrydb.com/managed-services/{id}/backups/{backup_id}/restore \
-H "Content-Type: application/json" \
-d '{
"target_service_name": "orders-db-from-backup",
"plan_name": "tier-2",
"zone": "se-sto1"
}'

Monitoring Restore Progress

curl -u $API_KEY:$API_SECRET \
https://api.foundrydb.com/managed-services/{restored_service_id} \
| jq '{name: .name, status: .status}'

Watch the status field transition from pending to provisioning to running. Once the status is running, your restored database is ready to accept connections.

Testing Your Backups

A backup you have never restored is a backup you cannot trust. FoundryDB makes it easy to test restores because every restore creates a new, independent service. There is no risk to your production data.

A simple monthly practice:

  1. Trigger a manual backup of your production service.
  2. Restore it to a new service with a test name.
  3. Connect to the restored service and run validation queries against your data.
  4. Delete the test service when you are done.
# 1. Trigger manual backup
curl -u $API_KEY:$API_SECRET -X POST \
https://api.foundrydb.com/managed-services/{id}/backups \
-H "Content-Type: application/json" \
-d '{"backup_type": "manual"}'

# 2. Restore to a test service (use the backup ID from step 1)
curl -u $API_KEY:$API_SECRET -X POST \
https://api.foundrydb.com/managed-services/{id}/backups/{backup_id}/restore \
-H "Content-Type: application/json" \
-d '{
"target_service_name": "monthly-restore-test",
"plan_name": "tier-2",
"zone": "se-sto1"
}'

# 3. Validate data on the restored service
PGPASSWORD=restored_pass psql \
"host=monthly-restore-test.foundrydb.com user=app_user dbname=defaultdb sslmode=verify-full" \
-c "SELECT count(*) FROM orders;"

# 4. Clean up
curl -u $API_KEY:$API_SECRET -X DELETE \
https://api.foundrydb.com/managed-services/{restored_service_id}

This costs only the compute time for the restored service (minutes, not hours) and gives you confidence that your backups are actually recoverable.

Retention Policies

Backup typeRetention
Automated daily7 days
ManualUntil deleted
WAL / binlog / oplog (PITR window)7 days

Manual backups are never automatically deleted. If you create manual backups before deployments, remember to clean up old ones periodically:

curl -u $API_KEY:$API_SECRET -X DELETE \
https://api.foundrydb.com/managed-services/{id}/backups/{backup_id}

Disaster Recovery Checklist

Before you need to restore in a real incident, prepare now:

  1. Test restores regularly. Restore to a new service and verify your data. Monthly is a good cadence.
  2. Verify PITR is active. Check your service metrics to confirm WAL/binlog/oplog archiving is running continuously.
  3. Document your RTO and RPO. Know how long a restore takes for your database size and how much data loss you can tolerate.
  4. Take manual backups before risky operations. Schema migrations, bulk deletes, and version upgrades all warrant a pre-change backup.
  5. Keep your allowed_cidrs updated. A restored service inherits the source service's network rules. Make sure your application can connect.

What's Next

Backups and PITR are available on every FoundryDB service with no additional configuration. If you are running a database that matters, take 10 minutes to test a restore today. The best time to discover a problem with your backup strategy is before you need it.

Read the full Backups and Restore documentation for API details and per-engine specifics. If you are not yet on FoundryDB, create your first service and see automated backups working within minutes.