<div align="center"
pgproof
Postgres & MySQL backups you've proven restore.
</div
A backup you haven't restored is a hope, not a backup. pgproof dumps your database, encrypts it, ships it to S3/R2/local/Telegram — and then restores it into a throwaway database to prove it actually works. If a backup can't be restored, it pings you on Telegram today, not the morning your primary dies.
<p align="center" <img src="docs/demo.svg" alt="pgproof backing up a database, proving it restores, and catching a corrupted artifact" width="860" </p
That verified ✓ is the whole point. Every other line of this README is in service of it — and the last two commands above are why: when the stored artifact is damaged, verify fails loudly instead of reporting a backup you don't have.
---
Why another backup tool?
| | restore-test built in | single static binary | encrypted | S3/R2 + Telegram | one-command restore | |---|:---:|:---:|:---:|:---:|:---:| | pgproof | ✅ every backup | ✅ | ✅ age | ✅ | ✅ | | pgdump + cron + s3 | ❌ | — | DIY | DIY | ❌ | | postgres-backup-s3 (Docker) | ❌ | ❌ | gpg | ❌ Telegram | ❌ | | pgBackRest / Barman | manual | ❌ | ✅ | ❌ | partial |
pgBackRest and Barman are excellent for large, WAL-based, point-in-time setups. pgproof is for the other 90%: a homelab, a side project, a small SaaS that just wants nightly logical backups it can trust, with zero moving parts.
Features
- 🔁 Verified restores — after each backup, pgproof spins up a throwaway
database, restores into it, checks it has tables (and optionally that key tables aren't empty), then drops it. No manual fire drills.
- 🔒 Encrypted at rest — streaming age
encryption, passphrase or public-key. Multi-GB dumps never touch RAM.
- ☁️ Anywhere storage — S3, Cloudflare R2, DigitalOcean Spaces, MinIO,
local/NAS path, and Telegram as a write-only off-site copy. Fan out to several at once.