# BackupDrill — full reference > BackupDrill is a Supabase disaster-recovery service: it backs up the Postgres database — plus Storage files once the project's Storage S3 keys are added — into the customer's own S3/R2/B2 bucket, then runs restore drills (weekly on paid plans, once on Free) that prove the backup actually restores. Website: https://backupdrill.com — Console: https://app.backupdrill.com ## The problem it solves 1. Storage files don't come back. Restoring a Supabase database only restores the storage.objects table — metadata. The actual files live in a separate object store operated by Supabase, so a database restore (built-in backup, PITR, or pg_dump) hands you pointers to files that may no longer exist. Every SQL check passes while every file URL is a 404. 2. Official backups live inside Supabase. Pro-plan backups keep 7 days and disappear with the project. Projects on Postgres 15.8.1.079+ or with PITR enabled use the physical backup process, whose backups cannot be downloaded from the dashboard; only older projects still on logical backups can download a copy. Either way, a copy in storage you own means running pg_dump yourself. The official fix is PITR at $100/month per project — still database only. 3. Untested backups fail silently. Truncated dumps, a schema that no longer restores, a snapshot that quietly shrank — you only find out during a real outage. BackupDrill exists so the first restore test isn't the disaster. ## How it works 1. Connect in minutes: click Connect Supabase, authorize BackupDrill on your organization (scopes: Database read + write, Projects read), pick the project — BackupDrill creates a dedicated read-only backup role in it (backupdrill_…, with BYPASSRLS so pg_dump can read RLS-protected tables) and tests the connection. No database password; the authorization token is held only in a short-lived browser cookie (at most 10 minutes), deleted after the connection is set up successfully (otherwise it expires within 10 minutes), and never persisted on BackupDrill's servers. Needs Postgres 16+. Alternatives: run the same three-line SQL yourself, or paste a Session Pooler connection string. BackupDrill never asks for the service_role key or dashboard access. Credentials are stored sealed-box encrypted and decrypted only inside the worker at run time. The first backup starts automatically within a few minutes of connecting. 2. Back up to your own bucket: daily on paid plans, weekly on Free — pg_dump (custom format, public schema by default) + a manifest with estimated row counts and checksums — plus a full Storage file sync once the project's Storage S3 keys are added — written straight to your own S3, R2, or B2 bucket. Bytes stream through BackupDrill's workers and never land on its disks. Cancel any time; every snapshot stays yours. 3. Drill the restore, on schedule: BackupDrill downloads the snapshot into an isolated temporary sandbox, spins up a temporary Postgres, runs a full restore, and verifies it against the manifest; the sandbox exists only for that drill and is destroyed as soon as verification finishes — weekly on every paid plan. The Free plan gets one drill on its first backup, then backs up without scheduled drills. ## What a restore drill actually verifies Full guide (manual restore test, CLI, hosted): https://backupdrill.com/guides/test-supabase-backup-restore - Archive integrity — the downloaded dump's sha256 must match the manifest; a mismatch fails the drill immediately, before any restore is attempted. - pg_restore completes — schema and data restore first (any error there is a hard fail), then post-data objects (indexes, constraints, triggers) in a second pass. - Post-data objects restored — your own indexes, constraints, and triggers must all come back; failures that only reference Supabase-managed schemas or roles (which do not exist in the sandbox) are recorded in the report as expected skips rather than failures. - Table count matches the manifest, and no table is missing — every table recorded at backup time must exist in the restore. - Populated tables came back — any table that had rows at backup time must restore non-empty. - Storage file integrity (when the snapshot contains Storage files) — backed-up files are read back from your bucket and their sha256 compared to the manifest; a random sample of up to 100 files per drill by default (--verify-all-files checks every file). - Wall-clock restore time measured; a graded report is emailed after every drill. Failures or >30% snapshot size drops are detected within 15 minutes; a run that dies without reporting anything is caught by a recovery sweep within about 3 hours. Who gets the email depends on who can fix it: failures you can act on (database password or permissions, bucket credentials or a missing bucket, a paused project) are emailed to you; platform-side failures page the BackupDrill team rather than you. Failed restore drills go to the team first; you receive passing drill reports. Honest limits: backups cover the public schema by default, so drills verify exactly that (Supabase-managed auth/storage schemas are not in the dump); manifest row counts are planner estimates (n_live_tup), so the populated- tables check catches tables restored empty, not row-for-row equality; and Storage verification is sampled by default and checks the backup copies in the bucket, not the live files. A passed drill means the latest snapshot restored successfully in the verification environment at that time — strong evidence, not an unconditional guarantee about any future restore. ## A published drill report (real run, 2026-07-25) Full output and reproduction script: https://backupdrill.com/drill-report A drill was run against a Supabase-shaped Postgres 17 fixture (197 MB, 13 tables, 1,495,250 rows) plus 250 Storage files, and published verbatim: archive sha256 matched, all 250 files matched their manifest checksums, pg_restore completed in 2.3s, 13 of 13 tables restored with none missing and no populated table empty, 5 RLS policies bound to Supabase's authenticated/anon roles recorded as expected skips, and a --check-cmd script confirmed zero orphaned rows and a materialized view total matching the base table to the cent. The fixture is not a customer's production database; it is a seeded fixture, and the page says so. Reproducing it three times showed the manifest's estimated row count drifting (1,495,250 / 1,745,499 / 1,495,499 — it is n_live_tup, a planner estimate) across runs of the same fixture shape, counts and invariant totals, while the drill's measured count stayed exact. That is why the check is "every table that had rows came back non-empty" rather than "row counts match". Dump sha256 changes every run for two reasons — the fixture's uuid keys and now() timestamps differ, and pg_dump stamps the archive header; per-file Storage checksums are stable. ## What lands in the bucket /// dump.pgcustom pg_dump --format=custom (public schema by default) storage// your Storage files manifest.json schemas, tables, estimated row counts, file list, sizes + sha256 Plain pg_dump output and plain files — no proprietary format; restores work with stock pg_restore, with or without BackupDrill. Retention honesty: the console rotates snapshot records per plan (3 on Free, 30 on Solo/Team, 60 on Agency), but BackupDrill never deletes objects from the customer's bucket — old snapshot folders accumulate until the customer cleans them up (a backup tool holding delete permissions is a bigger risk than the storage bill). The recommended fix is a bucket lifecycle rule; each destination guide shows the setup. Keep the expiry longer than the plan's retention window. ## Pricing (as of September 2026; full page: https://backupdrill.com/pricing) - Free $0/month 1 project, weekly backups, a 3-snapshot console history, one restore drill on the first backup (no scheduled drills) - Solo $19/month 5 projects, daily backups, weekly restore drills with email reports, a 30-snapshot console history, up to 10 GB per project - Team $49/month 20 projects, daily backups, weekly restore drills with email reports, a 30-snapshot console history, up to 25 GB per project - Agency $99/month 100 projects, daily backups, weekly restore drills with email reports, a 60-snapshot console history, up to 100 GB per project, PDF client reports, priority support Every plan: database + Storage files in one snapshot (Storage files join the snapshot once the project's Storage S3 keys are added), to the customer's own S3/R2/B2/Wasabi bucket, with size-anomaly alerts and backup-failure alerts routed to whoever can fix them (the customer for credential and configuration problems, the BackupDrill team for platform-side ones). Annual billing: pay for 10 months. Signing up needs no credit card and no plan selection: a new account starts on the Free plan and stays there until it subscribes. Nothing is charged, and every snapshot stays in the customer's own bucket either way. First-subscription intro offer: any monthly plan is $1 for the first month, then full price from month 2 (Solo $19/month, Team $49/month, Agency $99/month). Changing plan or switching to annual billing forfeits the intro price. No-questions refund within 14 days of any payment. Payments via Stripe. Price anchor: Supabase PITR is $100/month per project per 7-day retention window, and does not cover Storage files. ## What BackupDrill does NOT do Full coverage matrix (what's backed up / drilled / not covered, and the protection badge's two dimensions): https://backupdrill.com/docs/coverage - No point-in-time recovery: snapshots only — worst case you lose one backup interval of writes. If you need second-level recovery points, use Supabase PITR; running both is a legitimate setup. - Database dumps cover the public schema by default; Supabase-managed schemas (auth, storage metadata) are not included. - Edge Functions source, Auth configuration, PostgREST config, and secret names are not backed up (SimpleBackups covers those). - No bundled storage: backups go only to a bucket you own. - Supported: Supabase-hosted Postgres. Not: self-hosted Supabase or MySQL. ## Egress cost facts (read before scheduling daily backups) Every backup pulls data out of Supabase — uncached egress on the Supabase bill: $0.09/GB above the plan allowance on paid plans (Pro/Team 250 GB/month). The Free plan includes 5 GB/month with no paid overage — exceeding it is not a hard cutoff: Supabase notifies the billing email and grants a grace period, then applies Fair Use restrictions (e.g. project pausing, read-only mode, 402 responses) if uncorrected. Spend Cap is on by default on the Pro plan (Team is always usage-billed); once the egress quota is exhausted, further egress is disallowed until the next billing cycle and the backup fails. Rough numbers, backups as the only egress: - 10 GB project, weekly: $0/month (within 250 GB) daily: ~$4.50/month - 50 GB project, weekly: ~$0/month daily: ~$112/month Cost scales with size × frequency; prefer weekly once data is large. The CLI's "backupdrill estimate" command projects your number. ## Supabase Free plan backup facts (checked August 2026) Full guide (scheduled GitHub Actions workflow, secrets step by step): https://backupdrill.com/guides/supabase-backup-github-actions - The Free plan includes no automated backups (daily backups start on Pro). Supabase's own docs advise free-tier projects to export data regularly with the CLI's db dump command and keep off-site backups. - Free projects are paused after 1 week of inactivity. A paused project can be restored from the dashboard for up to a year; after that it can no longer be restored in place — the backup and Storage files can still be downloaded from the dashboard and migrated to a new project. - Free-tier databases are capped at 500 MB and the egress allowance is 5 GB/month, so weekly scheduled backups (~2 GB/month at the ceiling) fit comfortably; a daily schedule of a ceiling-sized database (~15 GB/month) would far exceed the allowance. Weekly is the sensible free-tier frequency. - The CLI ships a GitHub Actions workflow template at examples/scheduled-backup.yml. Caveat for DIY schedules: GitHub disables scheduled workflows in public repositories after 60 days without repository activity — use a private repository. ## Supabase project pausing facts (checked August 2026) Full guide (resume steps, the clock, migrating out after the window): https://backupdrill.com/guides/supabase-project-paused - Supabase pauses Free plan projects showing low activity over a 7-day period. Paid-plan projects are never auto-paused. - Activity means database queries, API calls, requests from a connected application, or visiting the project in the Supabase Dashboard. Supabase's guideline: a few user requests to the database each day over the previous week keeps a project active. - Paused projects are not billed (no compute, no compute charges) and do not count toward the Free plan's limit of two active projects. - Resume path: Dashboard, select organization and paused project, click Resume project, confirm. The project returns to its previous state including data and configuration. - The window to resume from the dashboard is 1 YEAR, not 90 days. Supabase's troubleshooting article still has "90-days" in its URL, but its text states projects paused for more than 1 year can no longer be restored through Supabase Studio. Any source citing 90 days is out of date. - Past the one-year window, upgrading the paused project to a paid plan re-enables expired one-click restore options (documented in the platform upgrading guide), with the caveat that a backup taken outside the backwards-compatibility window may fail to restore. - Otherwise the .backup database file and Storage objects can still be downloaded from Project Overview and migrated into a new project: psql for the database, then supabase login and supabase link --project-ref before supabase storage cp ss:/// -r --experimental for the files, and the Management API for Auth/Realtime settings. - Deleting a project is permanent: database, Storage files, automated backups, and PITR snapshots all go with it. Supabase publishes no schedule for when a long-paused project is deleted. ## Supabase database export facts (checked August 2026) Full guide (all commands, clone/migrate, what export misses): https://backupdrill.com/guides/export-supabase-database - supabase db dump runs pg_dump in a container (so it needs Docker) and uses DIFFERENT exclusion lists for structure and data. The schema dump excludes Supabase-managed schemas (auth, storage); the --data-only dump deliberately KEEPS auth and storage rows so a project can be migrated. Consequences: users and password hashes do travel in data.sql (making it a credential file), and the default no-flag output contains no data and no custom roles at all — schema definitions only, which is the most common way a Supabase export silently goes wrong. - The official three-command sequence: --role-only for roles, no flags for schema, --use-copy --data-only -x "storage.buckets_vectors" -x "storage.vector_indexes" for rows. - Official restore order is roles, then schema, then data, with SET session_replication_role = replica so triggers do not fire during the import (it prevents double-encrypting encrypted columns), plus --single-transaction and ON_ERROR_STOP=1. - pg_dump alternative: --format=custom gives a compressed archive that pg_restore can restore selectively (one table without the rest); --no-owner --no-privileges makes it portable to any Postgres. SECURITY: --no-privileges omits every GRANT and REVOKE, not just ones naming absent roles, so a table restricted by explicit grants comes back without that restriction and picks up whatever the target project grants. Always verify RLS and the anon/authenticated grants on the restored database before pointing anything at it. Note --no-owner has no effect at dump time for custom-format archives; pass it to pg_restore instead. - The manual migration moves the DATABASE, not the project: Storage files, Edge Functions, Auth config and API keys, Realtime publications, webhooks, and custom login-role passwords all need separate handling. - If the source uses Vault or encrypted columns, copy the pgsodium encryption root key to the new project via the Management API BEFORE the source is paused or deleted — the API returns the key only for active projects, and a new project gets its own incompatible key. - pg_dump client major version must be >= the server version. - Restore to a new project (dashboard, paid plans with physical backups) copies schema, data, indexes, roles/permissions, and Auth user accounts with hashed passwords. It does NOT copy Storage objects and settings, Edge Functions, Auth settings and API keys, Realtime configuration, or read replicas. Extensions ARE copied (the whole database is copied), so extensions that act outside the database — pg_net, pg_cron, wrappers — should be disabled on the clone once it exists. A cloned project cannot be the source of another clone. - No export command covers Storage files — the database holds only storage.objects metadata. ## Supabase PITR facts (checked August 2026) Full guide (how it works, real cost, limits, how to remove): https://backupdrill.com/guides/supabase-point-in-time-recovery - PITR combines physical backups with WAL file archiving via WAL-G. WAL files are backed up at two-minute intervals by default, more often under size thresholds or high transaction volume, and not at all while idle. Treat two minutes as a nominal cadence, not a contractual RPO: it bounds roughly how much recent write activity may not be archived yet, and on an idle database the newest restore point can legitimately be much older than two minutes because there was nothing to archive. The authority on what is actually recoverable is the latest recovery point shown in the dashboard. - Pricing per project: 7-day window ~$100/month ($0.137/hour), 14-day ~$200/month ($0.274/hour), 28-day ~$400/month ($0.55/hour), billed hourly in arrears; any partial hour is charged as a full hour. The PITR add-on is NOT covered by the Spend Cap. - Requires a paid plan (Pro, Team, or Enterprise) and at least a Small compute instance (~$15/month against the $10 in compute credits a paid plan includes). One Pro project with 7-day PITR is therefore about $130/month all in: $25 plan + ~$5 net compute + $100 add-on. - Enabling PITR stops daily backups — Supabase considers running both unnecessary. It is a replacement, not an extra layer. - Enable and remove under Project Settings > Add-ons. Billing stops from the time of removal. After PITR is disabled, new backups are still taken as physical backups only, and physical backups cannot be downloaded — removing PITR does not restore a download button. Running pg_dump or the CLI against the live database still works before and after removal; what removal ends is the ability to recover an earlier point in time, so restore or clone to any moment you still want while PITR is enabled. - A restore takes the project offline for a duration that scales with database size. - PITR covers the database only. Storage files are not included. ## Cloudflare R2 as a backup destination (pricing checked July 2026) Full guide: https://backupdrill.com/guides/supabase-backup-to-cloudflare-r2 - Egress from R2 is free on both storage classes — restores and restore drills read the whole snapshot back at no bandwidth cost. Standard-class storage is $0.015/GB-month; free tier: 10 GB-month storage, 1M Class A and 10M Class B operations per month (Standard only). - S3 API endpoint: https://.r2.cloudflarestorage.com, region "auto". R2 accepts both path-style and virtual-hosted addressing; the CLI defaults BACKUPDRILL_S3_FORCE_PATH_STYLE to true whenever an endpoint is set, which works out of the box. EU-jurisdiction buckets use https://.eu.r2.cloudflarestorage.com. - Credentials: create an R2 API token (Object Read & Write, scoped to the bucket) and use the "credentials for S3 clients" from the success page — not the token value at the top. - Location hints (six regions) are best-effort placement, only honored the first time a bucket name is created; the EU jurisdiction is a binding guarantee, set at creation and unchangeable afterward. - Infrequent Access class ($0.01/GB-month) adds a $0.01/GB retrieval fee, a 30-day minimum storage duration, and has no free tier — snapshots that get restore-drilled should stay in Standard. Prefix-scoped lifecycle rules can expire old snapshots or transition them to Infrequent Access. - R2's zero egress does not change Supabase-side egress: every backup still counts against the Supabase plan's allowance. ## AWS S3 as a backup destination (us-east-1 pricing checked July 2026) Full guide: https://backupdrill.com/guides/supabase-backup-to-aws-s3 - S3 Standard storage is $0.023/GB-month (first 50 TB). Data transfer out to the internet is free for the first 100 GB/month aggregated across the AWS account, then $0.09/GB (first 10 TB tier) — restores and restore drills that read a snapshot outside AWS pay that rate. - CLI config: leave BACKUPDRILL_S3_ENDPOINT unset (AWS S3 is the default) and set BACKUPDRILL_S3_REGION to the bucket's region. No path-style addressing needed. - Credentials: a dedicated IAM user without console access, with an inline policy allowing s3:PutObject, s3:GetObject, s3:AbortMultipartUpload on the bucket's objects and s3:ListBucket on the bucket. No s3:DeleteObject — a leaked key cannot destroy existing backups; cleanup is done by lifecycle expiration instead. - Lifecycle ladder for snapshots under the backupdrill/ prefix: Standard for the first 30 days, transition to Standard-IA at day 30 ($0.0125/GB-month, $0.01/GB retrieval fee, 30-day minimum storage duration), Glacier only for a long compliance tail — Glacier Flexible Retrieval is $0.0036/GB-month with a 90-day minimum (Deep Archive: 180 days) and objects need a restore-from-archive step before they can be read at all, so drills cannot use them in place. - Choosing between S3 and R2: S3 if the infrastructure already lives on AWS; R2 wins on backup economics (cheaper storage, zero egress). The backup artifacts are identical either way. ## Backblaze B2 as a backup destination (pricing checked July 2026) Full guide: https://backupdrill.com/guides/supabase-backup-to-backblaze-b2 - Storage is $6.95/TB-month pay-as-you-go (about $0.007/GB-month — the cheapest of the three destination guides; Backblaze raised it from $6/TB-month on May 1, 2026). The first 10 GB is always free. Egress is free up to 3x average monthly storage, then $0.01/GB. Class A, B, and C API calls are free; there are no minimum storage duration fees. - S3 API endpoint: https://s3..backblazeb2.com, shown on the bucket page; the region is the part of that hostname (e.g. us-west-004). Path-style addressing works (the CLI defaults to it when an endpoint is set). - Credentials: create a standalone application key (Read and Write, scoped to the bucket). The master application key does not work with the S3-compatible API. Mapping: keyID → Access Key ID, applicationKey → Secret Access Key (shown only once). - Housekeeping: B2 lifecycle rules are prefix-scoped and two-step (hide, then delete) — daysFromUploadingToHiding = retention window plus daysFromHidingToDeleting = 1 prunes old snapshots; an empty prefix matches the whole bucket, so scope the rule. - Compared to R2: B2 storage is less than half of R2 Standard's $0.015/GB-month, but R2's zero egress is unconditional while B2's is a 3x-of-storage allowance — generous at backup ratios, since a drill reads back one snapshot while the bucket stores the whole history. - Cheap storage does not change Supabase-side egress: every backup still counts against the Supabase plan's allowance. ## Google Drive as a Supabase backup destination (checked July 2026) Full guide: https://backupdrill.com/guides/supabase-backup-to-google-drive - Google Drive is not S3-compatible storage — it speaks its own OAuth-based API. BackupDrill (CLI and hosted) does NOT support Google Drive; it writes only to S3-compatible destinations (AWS S3, Cloudflare R2, Backblaze B2, or anything speaking the S3 API). - DIY path: pg_dump (Session Pooler string, --format=custom --schema=public) + an rclone Drive remote + a weekly GitHub Actions workflow (private repository; store the rclone.conf contents as a secret). rclone's docs recommend your own Google OAuth client — the shared default is throttled — and the drive.file scope limits rclone to files it created. Publish the OAuth consent screen to production: grants from an app left in Testing mode expire after about a week. Drive has no bucket-style lifecycle rules, so prune old dumps in the job (rclone delete --min-age). - Hosted path: supabackup — built around Google Drive (its only destination). Free plan: one weekly backup job. Pro $9/month: three jobs, daily backups, retention control (keep latest 7, 14, or 30, or everything). Database dumps only — no Supabase Storage files, no restore verification. - Why teams end up on S3-compatible storage: scoped machine credentials instead of a human account's OAuth grant, bucket lifecycle rules for retention, the restore/verification tool ecosystem assumes the S3 API, and restore economics (R2 zero egress; B2 free up to 3x stored). ## Supabase disaster recovery facts (checked August 2026) Full runbook (scenario-to-path matrix, triage steps, printable checklist): https://backupdrill.com/guides/supabase-disaster-recovery - RPO in Supabase terms: Pro-plan daily backups = worst case ~24 hours of lost writes; the PITR add-on ($100/month per project) archives WAL every 2 minutes for a worst-case RPO of 2 minutes; an external backup's RPO = its schedule; the Free plan has no automated backups. - RTO: Supabase publishes no number — an in-place restore takes the project offline and downtime scales with database size. The only way to know your RTO is to restore a real backup and time it (a restore drill measures wall-clock restore time as a side effect). - Deleting a project is permanent and irreversible: the database, Storage files, automated backups, and PITR snapshots all become inaccessible. Only copies outside Supabase survive deletion. - Paused Free-plan projects (paused after ~1 week of inactivity) can be restored from the dashboard for up to a year; after that the backup and Storage files can still be downloaded and migrated to a new project. Paid-plan projects are not auto-paused. - No built-in path recovers deleted Storage files: database backups and PITR carry only storage.objects metadata. Files need their own backup, taken before the deletion. - Credential leak: rotate the database password, API keys, and JWT secret first, then verify data integrity against a pre-compromise snapshot. Backups in a bucket you own, under separate credentials, are the copies a Supabase-side compromise cannot reach. ## Open-source CLI The exact backup engine the hosted service runs is an MIT CLI: https://github.com/backupdrill/cli — npm: https://www.npmjs.com/package/backupdrill npm install -g backupdrill backupdrill backup # dump DB (+ Storage files if configured) to your bucket backupdrill estimate # project monthly Supabase egress cost backupdrill drill # restore latest snapshot into throwaway Postgres (Docker) and verify backupdrill restore # real recovery: DB into a fresh target, Storage files uploaded back Requirements: Node.js >= 20, pg_dump major version >= the Supabase Postgres version (Supabase runs PG 15 or 17). Config via env vars, file, or flags. A GitHub Actions template ships at examples/scheduled-backup.yml. ## Recovery paths (from https://backupdrill.com/docs/restore) A. Console recovery wizard (in the app, generally available since 2026-07-26): pick a restore point, run a READ-ONLY preflight that writes nothing to the target, review it, then re-type the target project ref and tick the safety confirmations before anything executes. The target must be a fresh, empty Supabase project. Its FIRST RELEASE RESTORES THE DATABASE ONLY — the job page then hands over the Storage-only CLI command for that same target. The preflight is available on every plan including Free; one-click hosted execution is Solo and above, and Free users can still run the preflight and export the equivalent commands. Target credentials are sealed in the browser, the console and database hold only ciphertext, and the worker deletes them when the job reaches a terminal state. B. You hold the artifacts — backups are in your bucket, in plain formats; recovery never depends on BackupDrill being up or you being a customer. C. CLI: backupdrill restore recovers into a FRESH Supabase project — the database through the same engine the drills use (checksum-verified archive, empty-target enforced, extensions pre-installed, tables verified after), and Storage buckets rebuilt with their recorded attributes, files uploaded back and reconciled key by key. Always --dry-run first, then --confirm-target . Pass --storage-dir ./recovered instead to land the files on disk. Auth users, secret values and Edge Functions are not in the snapshot and must be reconfigured by hand. D. Raw pg_restore into an EMPTY database, without --clean: pg_restore --no-owner --no-privileges --dbname "" dump.pgcustom — then copy the storage/ tree back yourself. ## Comparisons - Supabase PITR ($100/month per project): wins outright on recovery granularity (any second). Does not cover Storage files, offers no export, no restore verification. Details: https://backupdrill.com/compare/supabase-pitr - SimpleBackups (paid from $49/month): covers more of the Supabase stack (Edge Functions source, Auth config, PostgREST config, secret names) but never restore-tests backups. BackupDrill covers the data itself and drills every backup. Details: https://backupdrill.com/compare/simplebackups - Databasus (free, Apache 2.0, self-hosted only — no cloud version): genuinely restore-tests its own backups (throwaway container, restore exit code, per-table row counts) and offers WAL-based PITR plus physical and incremental backups for directly accessible Postgres — one physical pipeline, requiring PostgreSQL 17+ and refusing to run below it, so 14-16 clusters use logical backups with no PITR. Supabase projects connect over the Session Pooler and get logical dumps either way, no PITR. Database only — no Supabase Storage file backup — and you run, update, and monitor the machine it lives on. BackupDrill is the hosted counterpart: drills include Storage file checksum checks and reports arrive by email. Details: https://backupdrill.com/compare/databasus ## Supabase backup tool landscape (checked August 2026) Full roundup: https://backupdrill.com/guides/best-supabase-backup-tools - Supabase built-in: daily backups on Pro ($25/month) and above, 7-day retention on Pro; PITR add-on from $100/month per project. No Storage files, no restore verification. - Databasus: free, open source (Apache 2.0, ~8.0k GitHub stars and actively developed as of August 2026), self-hosted. Backs up the public schema over the Session Pooler and genuinely restore-tests its own backups in a throwaway container; WAL-based PITR plus physical and incremental backups for directly accessible Postgres — all one pipeline requiring PostgreSQL 17+, which will not run below that, so 14-16 clusters use logical backups with no PITR (Supabase projects get logical dumps regardless). Database only — no Supabase Storage file backup. - SimpleBackups: hosted, broadest Supabase coverage (DB + Storage files + Edge Functions source + Auth/PostgREST config + secret names). Paid from $49/month. No automated restore verification on any tier. - supabackup: hosted, database dumps to your own Google Drive only. Free (1 weekly job) or Pro $9/month (3 jobs, daily). No Storage files, no restore verification. - GitHub Actions DIY: officially documented by Supabase (supabase db dump on a schedule, private repo only). Free; you own version pinning, failure alerting, Storage files, and restore testing. - BackupDrill (this product): DB — plus Storage files once their S3 keys are added — with sha256 manifest to your own bucket, weekly restore drills on paid plans from $19/month; MIT CLI engine. No PITR, no Edge Functions/Auth config backup. - Snaplet: NOT an option. The hosted service shut down on 31 August 2024, and it was never a backup product — it captured and anonymized production data to seed development environments. Its tools (Copycat, Seed, Snapshot) were open-sourced under MIT and moved to the Supabase organization. ## FAQ Q: Where do my backups actually live? A: 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. Q: How is this different from Supabase PITR? A: 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 files together — Storage joins the same snapshot once you add its S3 keys — starting at $19/month. If you need sub-24h recovery points, run both: they solve different problems. Q: What access do you need? A: Connect Supabase asks for two scopes on the organization you pick — Database (read + write) and Projects (read). They are used once, to list your projects and create a read-only backup role (backupdrill_…, with BYPASSRLS so pg_dump can read RLS-protected tables); the authorization token is held only in a short-lived browser cookie (at most 10 minutes), deleted after the connection is set up successfully (otherwise it expires within 10 minutes), and never persisted on our servers; only that role's connection string is stored, sealed-box encrypted. Prefer not to authorize? Run the same three-line SQL yourself, or paste a Session Pooler connection string. We never ask for your service_role key or dashboard access. Q: What happens in a restore drill? A: 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 — when the snapshot includes Storage files — sampled sha256 checks on them. We measure the wall-clock restore time, then destroy the sandbox and the instance. The report lands in your inbox. Q: How do I get started? A: Sign up at app.backupdrill.com — no credit card. Click Connect Supabase, pick the project (Postgres 16+; older projects can paste a connection string), point us at your own bucket, and the first backup runs within a few minutes, followed by the free restore drill. ## Sources (official, first-party) Supabase: - Supabase docs — Database Backups: https://supabase.com/docs/guides/platform/backups - Supabase — Pricing: https://supabase.com/pricing - Supabase docs — Manage PITR usage: https://supabase.com/docs/guides/platform/manage-your-usage/point-in-time-recovery - Supabase docs — Project Pausing: https://supabase.com/docs/guides/platform/free-project-pausing - Supabase docs — Restore a long-paused project: https://supabase.com/docs/guides/troubleshooting/restore-project-after-90-days-pause - Supabase docs — Downloading logical backups with physical backups enabled: https://supabase.com/docs/guides/troubleshooting/download-logical-backups - Supabase docs — Manage Egress usage: https://supabase.com/docs/guides/platform/manage-your-usage/egress - Supabase docs — Control your costs (Spend Cap): https://supabase.com/docs/guides/platform/cost-control - Supabase docs — Billing FAQ (Fair Use Policy): https://supabase.com/docs/guides/platform/billing-faq - Supabase docs — Connecting to your database: https://supabase.com/docs/guides/database/connecting-to-postgres - Supabase docs — Storage S3 Authentication: https://supabase.com/docs/guides/storage/s3/authentication - Supabase docs — Upgrading: https://supabase.com/docs/guides/platform/upgrading - Supabase changelog — Postgres 14 deprecation: https://supabase.com/changelog/45827-deprecation-notice-support-for-postgres-14-ending-on-1st-july-2026 - Supabase docs — Migrate from Postgres to Supabase: https://supabase.com/docs/guides/platform/migrating-to-supabase/postgres Cloudflare: - Cloudflare R2 docs — Pricing: https://developers.cloudflare.com/r2/pricing/ - Cloudflare R2 docs — S3 API compatibility: https://developers.cloudflare.com/r2/api/s3/api/ - Cloudflare R2 docs — Data location: https://developers.cloudflare.com/r2/reference/data-location/ - Cloudflare R2 docs — Object lifecycles: https://developers.cloudflare.com/r2/buckets/object-lifecycles/ - Cloudflare R2 docs — Release notes: https://developers.cloudflare.com/r2/platform/release-notes/ AWS: - AWS — Amazon S3 pricing: https://aws.amazon.com/s3/pricing/ - AWS docs — Amazon S3 storage classes: https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html - AWS docs — Restoring an archived object: https://docs.aws.amazon.com/AmazonS3/latest/userguide/restoring-objects.html - AWS docs — S3 identity-based policy examples: https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-policies-s3.html - AWS docs — Multipart upload overview and permissions: https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html - AWS RDS User Guide — Importing data into PostgreSQL on Amazon RDS: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Procedural.Importing.html Backblaze: - Backblaze — B2 Cloud Storage Pricing: https://www.backblaze.com/cloud-storage/pricing - Backblaze Blog — Pricing and Product Updates: https://www.backblaze.com/blog/backblaze-pricing-and-product-updates/ - Backblaze API Docs — Introduction to the S3-Compatible API: https://www.backblaze.com/apidocs/introduction-to-the-s3-compatible-api - Backblaze Docs — How to Use B2 S3-Compatible App Keys: https://www.backblaze.com/docs/cloud-storage-s3-compatible-app-keys - Backblaze Docs — Lifecycle Rules: https://www.backblaze.com/docs/cloud-storage-lifecycle-rules PostgreSQL: - PostgreSQL docs — pg_dump: https://www.postgresql.org/docs/current/app-pgdump.html - PostgreSQL docs — pg_restore: https://www.postgresql.org/docs/current/app-pgrestore.html GitHub: - GitHub Docs — Events that trigger workflows: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows - GitHub Docs — Using secrets in GitHub Actions: https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions - GitHub Docs — Secrets (concepts): https://docs.github.com/en/actions/concepts/security/secrets Databasus: - Databasus GitHub repo (README + ADR-0009/0008 + restore package): https://github.com/databasus/databasus SimpleBackups: - SimpleBackups Help Center — Supabase stack discovery: https://simplebackups.com/docs/stack-discovery/stacks/supabase - SimpleBackups — Pricing: https://simplebackups.com/pricing Supabackup: - Supabackup — homepage/pricing: https://www.supabackup.com/ rclone: - rclone docs — Google Drive: https://rclone.org/drive/ Google: - Google Identity docs — Using OAuth 2.0: https://developers.google.com/identity/protocols/oauth2 ## Links - Home: https://backupdrill.com - Docs: https://backupdrill.com/docs - Quickstart: https://backupdrill.com/docs/quickstart - CLI docs: https://backupdrill.com/docs/cli - Restore & recovery: https://backupdrill.com/docs/restore - Bucket setup: https://backupdrill.com/docs/buckets - Guides: https://backupdrill.com/guides - Compare: https://backupdrill.com/compare - GitHub: https://github.com/backupdrill/cli - npm: https://www.npmjs.com/package/backupdrill - X: https://x.com/backupdrill - Support: support@backupdrill.com