pg_dump the database.
Two reasons to back up:
- Disaster recovery — restore on a new host if the server dies.
- Schema rollback — migrations are forward-only. If an upgrade damages data or you need the old shape back, only a backup recovers it cleanly.
Local Postgres (docker compose)
-Fc = custom format, smaller and restore-flexible.
Restore on a fresh container:
Managed Postgres (Neon / Supabase / Railway / Fly Postgres)
Each provider has its own snapshot mechanism. Don’t rely on theirs alone — they all have edge cases (Neon’s free branches expire, Railway’s snapshots disappear with a project delete). Schedule your ownpg_dump to S3 / B2 / GCS in parallel.
What’s in there
wallet_config contains the .p12 password in plaintext, and notification
tables can contain webhook targets and signing secrets. Dump files should be
encrypted at rest (gpg --symmetric, or rely on bucket-level KMS).
Retention
Hit / notification growth is the table to watch. With heavy use a single high-traffic key can add 10k+ rows/day. Built-in retention (see.env.example):
/api/cron/notifications. All unset = retain forever — appropriate for
low-traffic deployments.
Manual cleanup if you don’t want a fixed retention:
Restoring a single key
If you accidentallyDELETE FROM keys WHERE id = ..., restoring just that row from a dump:
mantis-restore DB around for the most recent dump and copy rows over as needed.