Skip to main content

Database Forking: Create Production Clones for Testing in Minutes

· 7 min read
FoundryDB Team
Engineering @ FoundryDB

Testing against realistic data is the difference between catching bugs before production and catching them in production. But getting a faithful copy of your production database into a staging environment usually means writing export scripts, waiting for dumps to transfer, provisioning infrastructure, and importing the data. For a 100 GB PostgreSQL database, that process can take hours and requires someone to babysit it.

FoundryDB's fork endpoint eliminates this entire workflow. One API call creates a fully independent copy of your database, running on its own VM with its own credentials, restored from a backup of the source service. The source database is never touched. The fork is provisioned, restored, and ready for connections in minutes.

What Is a Database Fork?

A fork creates a new FoundryDB service by restoring from a backup of an existing service. The new service inherits the same database engine, version, compute plan, storage configuration, zone, and allowed CIDRs as the source. Once provisioned, it is completely independent: it has its own VM, its own DNS endpoint, its own credentials, and its own backup schedule.

The fork is not a read replica. There is no replication link to the source. Writes to the fork do not affect the source, and writes to the source do not appear in the fork. This isolation is what makes forks safe for destructive testing.

Forking is supported for PostgreSQL, MySQL, MongoDB, Valkey, and Kafka. All database engines that support backups can be forked.

Why Fork Instead of Dump and Restore?

The traditional approach to creating a test copy of a production database involves pg_dump, mysqldump, or mongodump, a file transfer, and a manual import on the target. This has three problems.

It is slow. Dumping and restoring a large database can take hours. Forking uses FoundryDB's existing backup infrastructure (pgBackRest for PostgreSQL, native backup tooling for other engines), which is already optimized for speed.

It is manual. Someone has to run the dump, transfer the file, create the target database, import the data, and verify the result. Forking is one API call.

It touches production. Running pg_dump on a production database adds load to the primary. Forking restores from an existing backup, so the source database sees zero additional load.

Use Cases

Staging environments

Fork your production database before each release to validate migrations and application changes against real data. Since forks are cheap and fast, you can create a fresh one for every deploy cycle instead of maintaining a long-lived staging database that drifts out of sync.

Schema migration testing

Run your migration scripts against a fork before applying them to production. If the migration fails or produces unexpected results, delete the fork and iterate. The production database is never at risk.

Load testing

Fork your database, point your load testing tool at the fork's DNS endpoint, and run your benchmarks against realistic data volumes. When the test finishes, delete the fork.

Feature branch databases

Give each feature branch its own database fork. Developers can test against production-scale data without competing for shared staging resources. Combined with FoundryDB's TTL (auto-deletion) feature, these forks can clean themselves up automatically.

Creating a Fork via the API

The fork endpoint is POST /managed-services/{source-service-id}/fork. The source service must be in Running state and must have at least one completed backup.

Fork from the latest backup

If you omit backup_id, FoundryDB uses the most recent completed backup automatically.

curl -u $API_KEY:$API_SECRET -X POST \
https://api.foundrydb.com/managed-services/{source-id}/fork \
-H "Content-Type: application/json" \
-d '{"name": "staging-fork"}'

The response is a 202 Accepted with the new service object. The status field will show the initial provisioning state. The fork goes through the standard provisioning pipeline (network, server, agent, DNS, restore, health check) and transitions to Running once the backup has been restored and validated.

Fork from a specific backup

If you need to fork from a particular point in time, pass the backup_id explicitly. First, list the available backups for the source service.

# List completed backups for the source service
curl -u $API_KEY:$API_SECRET \
https://api.foundrydb.com/managed-services/{source-id}/backups \
| jq '.backups[] | select(.status == "Completed") | {id, created_at, type}'
[
{"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "created_at": "2026-04-05T02:00:00Z", "type": "automated"},
{"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "created_at": "2026-04-04T02:00:00Z", "type": "automated"}
]

Then create the fork from the specific backup.

curl -u $API_KEY:$API_SECRET -X POST \
https://api.foundrydb.com/managed-services/{source-id}/fork \
-H "Content-Type: application/json" \
-d '{
"name": "pre-migration-snapshot",
"backup_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}'

Fork Isolation

Each fork runs on a completely separate VM. There is no shared infrastructure between the source and the fork.

PropertySource serviceForked service
VMOriginal VMNew, dedicated VM
DNS endpointOriginal domainNew, unique domain
CredentialsOriginal users/passwordsNew, independent credentials
Backup scheduleExisting scheduleNew, independent schedule
Allowed CIDRsInherited at fork timeIndependently configurable
Compute planOriginal planSame plan (independently scalable)

After the fork is created, you can modify it without affecting the source. Scale it up, scale it down, change the allowed CIDRs, create new database users, or drop tables. None of these operations propagate back to the source.

Monitoring Fork Progress

Forked services go through the same provisioning pipeline as new services. You can monitor progress using the task summary endpoint.

curl -u $API_KEY:$API_SECRET \
https://api.foundrydb.com/managed-services/{fork-id}/task-summary \
| jq '{status, current_task, progress_pct}'

The fork transitions through these states: SetupNetwork, SetupServer, SetupAgent, SetupDNS, ProvisioningRestore (where the backup is restored), ProvisioningHealth, and finally Running.

Cleanup

Forks are full services with their own compute and storage resources. Remember to delete them when you are done.

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

For ephemeral use cases like CI/CD pipelines or feature branch databases, consider setting a TTL when creating your services. FoundryDB supports auto-deletion after a configurable number of hours (1 to 720), so your test forks clean themselves up without manual intervention.

CI/CD Integration

Database forks fit naturally into CI/CD pipelines. Here is a pattern for GitHub Actions that creates a fork before running migration tests and tears it down afterward.

jobs:
migration-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Fork production database
id: fork
run: |
RESPONSE=$(curl -s -u ${{ secrets.FDB_API_KEY }}:${{ secrets.FDB_API_SECRET }} \
-X POST https://api.foundrydb.com/managed-services/${{ vars.PROD_SERVICE_ID }}/fork \
-H "Content-Type: application/json" \
-d '{"name": "ci-migration-${{ github.run_id }}"}')
echo "fork_id=$(echo $RESPONSE | jq -r '.id')" >> $GITHUB_OUTPUT

- name: Wait for fork to be ready
run: |
for i in $(seq 1 60); do
STATUS=$(curl -s -u ${{ secrets.FDB_API_KEY }}:${{ secrets.FDB_API_SECRET }} \
https://api.foundrydb.com/managed-services/${{ steps.fork.outputs.fork_id }} \
| jq -r '.status')
if [ "$STATUS" = "Running" ]; then break; fi
sleep 10
done

- name: Run migrations against fork
run: ./run-migrations.sh --target ${{ steps.fork.outputs.fork_id }}

- name: Delete fork
if: always()
run: |
curl -s -u ${{ secrets.FDB_API_KEY }}:${{ secrets.FDB_API_SECRET }} \
-X DELETE https://api.foundrydb.com/managed-services/${{ steps.fork.outputs.fork_id }}

This pattern ensures every pull request validates migrations against a fresh copy of production data, and the fork is always cleaned up, even if the migration step fails.

What's Next

Database forking is available today for PostgreSQL, MySQL, MongoDB, and Valkey services on FoundryDB. To get started:

If you are not yet on FoundryDB, sign up and have your first database running in under five minutes.