Supabase backups and point-in-time recovery, explained

By the SupaHost team · Updated 11 November 2026 · 8 min read · View as Markdown

On Supabase Cloud, paid projects get automatic daily database backups (kept 7 days on Pro, 14 on Team, up to 30 on Enterprise), and point-in-time recovery is a paid add-on that starts at $100 a month per project. Those backups cover the Postgres database only: files in Storage are not included, so you need a separate plan for them. This guide explains how the backups work, how to take your own with pg_dump, and how to check that a restore actually works.

How Supabase Cloud backups work by plan

Supabase takes one backup of each project's database per day. How far back you can go depends on the plan. The figures below come from the Supabase backups docs and pricing page, checked in November 2026.

Plan Daily backups Point-in-time recovery
Free Not listed; Supabase recommends exporting your data yourself Not available
Pro Last 7 days Add-on, from $100/mo per project
Team Last 14 days Add-on
Enterprise Up to 30 days Add-on

A few details matter when you actually need a restore:

  • Restores cause downtime. The project is unavailable while it restores, and bigger databases take longer.
  • Custom role passwords aren't stored. If you created your own Postgres roles with passwords, you'll need to set those passwords again after a restore.
  • Replication needs attention. The docs say to drop your own subscriptions and replication slots before restoring and recreate them after. The slot Realtime uses is handled for you.
  • Deleting a project deletes its backups. You can't get a deleted project back from Supabase's backups. If you might need the data later, export it first.

If you're on the Free plan, there's no daily backup to fall back on. Taking your own dumps (covered below) is the only safety net.

Point-in-time recovery (PITR)

Daily backups mean you can lose up to a day of writes. Point-in-time recovery closes that gap. Supabase pairs physical snapshots with continuous archiving of the Postgres write-ahead log (WAL), the record of every change, and can replay it to any moment inside your retention window.

According to the docs, WAL files are uploaded every two minutes by default, or sooner when they get large. That means the most data you should lose is about two minutes' worth. When nothing is being written, nothing is uploaded.

Things to know before you turn it on:

  • The 7-day window costs from $100/mo per project. Longer windows cost more; the backups docs list the current options.
  • Enabling PITR replaces the daily backups for that project.
  • A PITR restore overwrites the current database. If you want to keep what's there now (for example, to pull out a few rows deleted by mistake), restore into a new project instead.

PITR is worth paying for when losing a day of writes would really hurt: orders, payments, user-generated content. For a side project or internal tool, daily backups plus your own dumps are often enough.

Logical vs physical backups

There are two kinds of Postgres backup, and they behave differently.

Logical backup Physical backup
What it is SQL (or an archive) that rebuilds tables and reloads rows A copy of the database's data files
Made with pg_dump, supabase db dump Platform tooling (snapshots plus WAL)
Restore speed Slower; rows are reloaded and indexes rebuilt Faster for large databases
Portability Restores into any compatible Postgres Tied to the same Postgres major version and setup
Point-in-time No, it's a single moment Yes, when combined with WAL

Supabase's daily backups are physical on newer Postgres versions (15.8.1.079 and up, per the docs). Logical backups are the ones you make yourself, and they're the most useful for portability: you can open them, restore part of them, or load them somewhere else entirely.

Taking your own backups with pg_dump

Even with platform backups, it's worth keeping a copy you control. It protects you against account problems, mistakes that outlive your retention window, and moving providers.

pg_dump takes a consistent snapshot even while the database is in use, and it doesn't block reads or writes (PostgreSQL docs). Get the connection string from your project's database settings. Supabase's direct connection looks like postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres. If your network doesn't support IPv6, use the session pooler string shown in the dashboard instead.

A full dump in the custom format, which is compressed and works with pg_restore:

pg_dump -Fc \
  -d "postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres" \
  -f backup-$(date +%F).dump

Most apps keep their tables in public. If you only want your own schemas and not the Supabase-managed ones, name them with -n:

pg_dump -Fc -n public \
  -d "postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres" \
  -f app-$(date +%F).dump

Some practical notes:

  • Match versions. Use a pg_dump at least as new as your project's Postgres major version.
  • Roles aren't in the dump. pg_dump covers one database. Roles live at the cluster level. The Supabase CLI can dump them with supabase db dump --role-only.
  • The Supabase CLI is an option too. supabase db dump wraps pg_dump and handles Supabase-specific details. Supabase's own guide uses it to dump roles, schema and data as three files (backup and restore guide). The flag that picks the target project has changed between CLI versions, so check supabase db dump --help.
  • Store it somewhere else. A backup in the same account as the database doesn't help if you lose access to that account. Put it in separate storage and run the dump on a schedule.

What's not in database backups

The biggest gap is Storage files. Supabase's docs are clear: backups include the metadata about Storage objects (the rows in storage.objects) but not the files. If someone deletes a file and you restore the database, you get the row back but the file is still gone.

To back up files, copy them out of Storage on their own schedule. Supabase Storage supports the S3 protocol once you enable it in Storage settings, so most S3 clients can sync a bucket to other storage.

Other things to keep in mind:

  • Edge Function code isn't in the database. Keep it in version control.
  • Custom role passwords need to be set again after a restore, as noted above.
  • Vault and encryption keys. If you restore into a new project and use Vault, Supabase's guide says to copy the old project's root encryption key before the old project is paused or deleted.

Testing your restores

A backup you've never restored is only a guess. Test it regularly, and time it, because the restore time is how long you'll be down during a real incident.

  1. Create a scratch target. Use a new empty project or a local Postgres, never your production database.

  2. Restore the dump. For a custom-format file:

    pg_restore --no-owner --no-privileges \
      -d "postgresql://postgres:[PASSWORD]@[SCRATCH-HOST]:5432/postgres" \
      app-2026-11-11.dump
    

    --no-owner skips ownership commands, so the user you connect as owns the restored objects. If you dumped only public, restoring into a fresh Supabase project avoids clashes with schemas that already exist there.

  3. Check the data. Compare row counts on your key tables against production, and run the queries your app depends on.

    select count(*) from public.orders;
    select max(created_at) from public.orders;
    
  4. Write down how long it took and what broke. That becomes your runbook.

How SupaHost handles backups

SupaHost runs the open-source Supabase stack on a VM dedicated to your account, and it backs up every project's database daily to a private bucket in your instance's region.

SupaHost plan Daily database backups Point-in-time recovery
Builder 7 days No
Pro 7 days 7 days
Business 14 days 14 days

PITR is included in Pro and Business, not sold as an add-on. A few other things work differently:

  • One project at a time. An instance holds many projects, and you can restore one without touching the others.
  • The old database is kept. After a restore, the previous database is kept for 3 days in case you need something from it.
  • Measured restore times. In a restore drill on a Pro instance in November 2026, a 0.8 GB database took about 4 minutes end to end, with the project offline for about 55 seconds. A 4.1 GB database took about 12 minutes, with the project offline for about 4.5 minutes. The data was identical after every run.
  • Exports from the Backups tab. You can download a pg_dump of any project's database in one click. In a test, a 0.8 GB dump restored into a fresh Supabase Postgres in 29 seconds.

The same gap applies here: Storage files are not included in SupaHost's daily backups. They live on the instance's disk, and a database restore doesn't roll them back. You can download all of a project's Storage files at any time from the Backups tab as a .tar.gz with bucket settings and metadata. Do that on a schedule if your files matter. See the backups docs for the steps.

If you're moving from Supabase Cloud, the migration guide covers what the import copies. Supabase pricing explained has a full cost comparison.

FAQ

Does Supabase back up my database automatically?

On paid plans, yes. Supabase takes daily backups, kept 7 days on Pro, 14 on Team and up to 30 on Enterprise. The backups docs don't list automatic backups for Free projects, so take your own dumps.

Are Supabase Storage files included in backups?

No. Database backups include the metadata rows for Storage objects but not the files. Back up buckets separately, for example with an S3 client.

How much does Supabase point-in-time recovery cost?

It starts at $100 a month per project for a 7-day window, and longer windows cost more. Turning it on replaces daily backups for that project.

How do I back up a Supabase database myself?

Run pg_dump -Fc -d "<connection string>" -f backup.dump with the connection string from your project's database settings, or use supabase db dump. Store the file outside your Supabase account and restore it into a scratch project regularly to check it works.

Can I restore a Supabase backup without losing current data?

A PITR restore replaces the current database. To keep both, restore into a new project and copy across the rows you need.

Does a restore bring back deleted files?

No. Restoring the database brings back the storage.objects rows, but files deleted from Storage stay deleted. This is true on Supabase Cloud and on SupaHost.

Running several Supabase projects? SupaHost gives you your own server with the open-source Supabase stack and 5 to 30 projects for one monthly price. See plans or compare costs.