Storage files don’t come back
Restoring a Supabase database only restores storage.objects — the metadata. The actual files live in a separate object store, so a restore hands you a bucket index full of pointers to files that no longer exist.
DISASTER RECOVERY FOR SUPABASE
Database restores only bring back storage.objects metadata — your actual files live elsewhere. BackupDrill snapshots your database and Storage files into your own bucket, then runs managed restore drills — nothing for you to run — that rebuild your database and prove it comes back.
Fully hosted — no servers to run. Free plan: weekly backups for one project. Paid plans from $19/month — a fifth of Supabase PITR, which still skips your Storage files.
$ backupdrill drill --project acme-prod
✓snapshot fetcheds3://acme-backups/2026-07-03
✓archive sha256matches manifest ✓
✓temp postgres 16provisioned
✓pg_restore142 tables in 8m 12s
✓table count142 = manifest, none missing ✓
✓populated tablesall restored non-empty ✓
✓storage files100/100 sampled sha256 ✓
RESULT: RESTORABLE ✓restore time 11m 04s
report sent → email
Why this exists
Restoring a Supabase database only restores storage.objects — the metadata. The actual files live in a separate object store, so a restore hands you a bucket index full of pointers to files that no longer exist.
Pro-plan backups keep 7 days, can’t be downloaded to your own infrastructure, and disappear with the project. The official fix is PITR at $100/month per project — and it still doesn’t cover Storage files.
Truncated dumps, a schema that no longer restores, a snapshot that quietly shrank 40% — you only find out during a real outage. The first time you test a restore shouldn’t be the day you need it.
How it works
Paste your Session Pooler connection string — the postgres user in it works as-is, and we never ask for your service_role key. Your first backup starts automatically within a few minutes of connecting.
Daily on paid plans, weekly on Free: pg_dump (custom format) + a full Storage file sync + a manifest with estimated row counts and checksums — written straight to your own S3, R2, or B2 bucket. Bytes stream through our workers and never land on our disks.
We spin up a temporary Postgres, run a full restore, and verify it against the manifest: archive sha256, table count with no missing tables, populated tables restored non-empty, plus sampled sha256 checks on your Storage files — weekly on Team and Agency, monthly on Solo. You get a graded report with the measured restore time. Failures or >30% size drops alert you within 15 minutes.
Open source
The exact backup engine the hosted service runs is an open-source CLI. Your disaster-recovery tool shouldn't be a black box.
npm install -g backupdrill
backupdrill backup # your database + Storage files → your own bucket
backupdrill drill # prove the latest snapshot actually restoresDIY covers one-off backups. The hosted service runs this same engine on a schedule, drills every restore, and emails you when something is wrong — nothing for you to babysit.
Pricing
Supabase PITR: $100/month per project, Storage files not included. Start free, upgrade when you need daily backups and scheduled restore drills.
For side projects
$0/month
For products with real users
$19/month
For small teams
$49/month
For client work
$99/month
Every plan: database + Storage files in one snapshot, to your own S3/R2/B2 bucket, with failure and size-anomaly email alerts. Snapshot history counts console records — objects in your bucket stay yours (add a lifecycle rule to expire old ones).
Annual billing: pay for 10 months.
FAQ
In your own S3, R2, or B2 bucket — you bring the bucket, you hold the keys. During backups the bytes stream through our workers and are never written to our disks; a restore drill downloads your snapshot into an isolated temporary sandbox that is destroyed as soon as verification finishes. If you cancel tomorrow, every snapshot is still yours.
PITR gives you point-in-time recovery for $100/month per project — and still doesn’t cover Storage files. We sell verified daily snapshots of your database and Storage together, starting at $19/month. If you need sub-24h recovery points, run both: they solve different problems.
Your Session Pooler connection string — the postgres user in it works as-is, because it owns your tables and dumps pass row-level security. We never ask for your service_role key or dashboard access. A read-only backup_reader role is an advanced option that only works if your schema has no RLS-enabled tables. Credentials are stored sealed-box encrypted.
We download your latest snapshot into an isolated temporary sandbox, provision a temporary Postgres, restore into it, and verify it against the backup manifest: archive sha256, pg_restore completes, table count matches with no missing tables, populated tables restored non-empty, and sampled sha256 checks on your Storage files. We measure the wall-clock restore time, then destroy the sandbox and the instance. The report lands in your inbox.
Sign up free at app.backupdrill.com — no credit card on the Free plan. Connecting a project takes a few minutes: paste your Session Pooler connection string and point us at your own S3, R2, or B2 bucket. Your first backup runs automatically within a few minutes of connecting.
Backups to your own bucket, restore drills on a schedule, and a report that proves your data comes back. The Free plan covers one project with weekly backups.