Mantis stores everything in Postgres. Backup = 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 own pg_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):
The notify worker sweeps hourly. In serverless cron mode, the same sweep runs through /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 accidentally DELETE FROM keys WHERE id = ..., restoring just that row from a dump:
Easier: keep a full mantis-restore DB around for the most recent dump and copy rows over as needed.