# Supabase backups and point-in-time recovery, explained

> How Supabase backups work on each plan, when to pay for point-in-time recovery, how to take your own pg_dump backups, and what database backups leave out.

Source: https://supahost.app/guides/supabase-backups · Updated 2026-11-11

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](https://supabase.com/docs/guides/platform/backups) and [pricing page](https://supabase.com/pricing), 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](https://supabase.com/docs/guides/platform/backups) 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](https://www.postgresql.org/docs/current/app-pgdump.html)). 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`:

```bash
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`:

```bash
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](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore)). 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](https://supabase.com/docs/guides/storage/s3/compatibility) 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:

   ```bash
   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.

   ```sql
   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](/pricing) 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](/docs#backups) for the steps.

If you're moving from Supabase Cloud, the [migration guide](/migrate/supabase-cloud) covers what the import copies. [Supabase pricing explained](/guides/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.
