Your backups open without us
Every backup is a standard dump, compressed with zstd and encrypted with age. With your key and free tools, you can restore it on your own machine, even if backupd is gone.
PostgreSQL 17 and later, restored with your key and nothing from us:
age -d -i backupd.agekey app.pgdump.zst.age | zstd -d \
| pg_restore --no-owner --single-transaction -d "$TARGET_URL"For servers from 9.2 to 16, pipe pg_restore’s script through psql instead; the docs give the line.
What you need
- Your age key, added in Settings → Encryption.
- The file, from Download encrypted or straight from your own bucket.
- age, zstd, and your engine’s own restore tool.
Encryption
Every backup is compressed and encrypted with age before it’s stored. Add your own key to decrypt backups yourself.
Your keys
New backups are encrypted to every key here. Revoking a key only affects future backups.
- Laptop
age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg3f9a1c0be47d2a85Revoke - Ops team vault
age1zvkyg2lqzraa2lnjvqej32nkuu0ues2s82hzrye869xeexvn73equnujwjb81e07d95c42f3a0Revoke
backupd’s key
backupd keeps its own key for this workspace so it can run restores and restore tests. Its secret half is encrypted at rest.
age1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs3290gqStorage
2,317 backup files · 66.5 GB stored
| File | Size | Restore test | Created |
|---|---|---|---|
app-prod-2026-10-16-0900.pgdump.zst.age | 612 MB | Passed | 12 min ago |
billing-2026-10-16-0600.sql.zst.age | 88 MB | Not tested | 2 h ago |
app-prod-2026-10-16-0800.pgdump.zst.age | 611 MB | Passed | 1 h ago |
events-2026-10-16-0300.archive.zst.age | 1.4 GB | Passed | 9 h ago |
marketing-site-2026-10-13-0300.zip.age | 20 MB | Passed | 3 days ago |
Postgres
age -d -i backupd.agekey app.pgdump.zst.age | zstd -d \
| pg_restore --no-owner --single-transaction -d "$TARGET_URL"age -d -i backupd.agekey app.pgdump.zst.age | zstd -d \
| pg_restore --no-owner -f - | grep -v '^SET transaction_timeout' \
| psql --single-transaction -v ON_ERROR_STOP=1 "$TARGET_URL"MySQL and MariaDB
age -d -i backupd.agekey app.sql.zst.age | zstd -d \
| mysql --defaults-extra-file=target.cnf target_dbMongoDB
age -d -i backupd.agekey app.archive.zst.age | zstd -d \
| mongorestore --archive --uri "$TARGET_URI"Convex
age -d -i backupd.agekey app.zip.zst.age | zstd -d > snapshot.zip
npx convex import --replace-all snapshot.zipWhat each file holds
Beside every backup sits a manifest, encrypted the same way, with the counts per table and the checksum of the dump. Decrypt it to check a file before you restore it:
$ age -d -i backupd.agekey app-prod-2026-10-16-0900.pgdump.zst.age.manifest.age | jq .
{
"version": 1,
"createdAt": "2026-10-16T09:01:54.212Z",
"format": "pg_custom",
"codec": "zstd",
"engineVersion": "16.4",
"toolVersion": "pg_dump (PostgreSQL) 18.1",
"tables": [
{ "schema": "public", "name": "sessions", "rows": 1402377, "exact": true },
{ "schema": "public", "name": "orders", "rows": 96512, "exact": true }
],
"plaintextBytes": 3113851904,
"plaintextSha256": "9c1f…e07a",
"storedBytes": 641728512,
"storedSha256": "5b3d…41c2"
}Add your key first
A key added today opens every backup made after it. Starter is free for 14 days.