Supabase backup: how to back up a Supabase project
Supabase backup, step by step: how to backup a Supabase project with pg_dump, the Supabase CLI, point-in-time recovery, and automated off-site backups.

Supabase backup: what it takes to protect a project
Supabase gives you a managed PostgreSQL database, authentication, file storage, and Edge Functions. What it does not give you by default is a copy of that data somewhere you control.
If a table is dropped by mistake, a migration goes wrong, a key leaks, or a project is paused or deleted, the question is always the same: where is the last good copy, and how quickly can you restore it?
This guide walks through every practical way to back up a Supabase project, from a one-off manual dump to a fully automated off-site schedule, and explains what each method actually protects.
What a complete Supabase backup includes
A Supabase project is more than its tables. A backup that only covers the public schema will leave gaps at restore time.
| Covered by a plain pg_dump | Needs extra handling | |
|---|---|---|
| Tables, rows, indexes, constraints | ||
| Database functions, triggers, views | ||
| Row Level Security policies | ||
| Auth users (auth schema) | sometimes, with the right flags | |
| Storage objects (actual files) | ||
| Edge Functions source | ||
| Project settings and secrets |
Decide up front which of these you must be able to restore. For most applications the answer is: the database, the auth users, and the storage bucket contents.
Source: Supabase Docs — Database backups
Method 1: A manual backup with pg_dump
pg_dump is the standard PostgreSQL tool for producing a logical backup — a file of SQL statements that can rebuild the database.
Grab your connection string from the Supabase dashboard (Project Settings → Database → Connection string), then run:
pg_dump "postgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres" \
--clean --if-exists --quote-all-identifiers \
--schema public --schema auth --schema storage \
--file supabase-backup.sqlA few notes that save pain later:
- Use a
pg_dumpversion that matches or exceeds your server version, otherwise the dump can fail on newer syntax. - Include the
authschema if you need your users to exist after a restore. - The dump contains everything. Treat the file as a production secret, encrypt it, and never commit it to a repository.
This method is free and transparent. Its weakness is that it only runs when someone remembers to run it.
Related reading: How to restore a Supabase project from a SQL backup
Method 2: The Supabase CLI
The Supabase CLI wraps the same logical dump in commands that separate schema from data, which is convenient when you version-control your schema.
supabase db dump --db-url "$SUPABASE_DB_URL" -f schema.sql
supabase db dump --db-url "$SUPABASE_DB_URL" --data-only -f data.sqlThe CLI is the right tool for reproducible environments and migrations. It is still a manual, developer-triggered action unless you schedule it somewhere.
Source: Supabase CLI reference — db dump
Method 3: Supabase's built-in backups and PITR
Paid Supabase plans include daily backups, and Point-in-Time Recovery is available as an add-on that lets you roll a project back to a specific moment.
This is genuinely useful and you should turn it on if your plan supports it. Be clear about what it is, though: it is a recovery feature inside the platform that holds your production data. It restores into the same account. It does not help if the account itself is suspended, compromised, or the project is deleted, and free-plan projects do not get it at all.
3
copies of your data
2
different storage media
1
copy kept off-site
Method 4: Automate it with GitHub Actions
The common do-it-yourself answer is a scheduled GitHub Actions workflow that runs pg_dump on a cron and pushes the file to object storage.
- 1
Store the connection string
Add the database URL as an encrypted repository secret.
- 2
Schedule the workflow
Run a cron job daily, or more often for busy projects.
- 3
Run pg_dump in the job
Install a matching PostgreSQL client version in the runner.
- 4
Encrypt the artifact
Never leave an unencrypted dump sitting in a bucket.
- 5
Ship it off-site
Upload to storage outside your Supabase account.
- 6
Alert on failure
A silent failed job is worse than no backup at all.
It works, and it is free in credit terms. What it costs is attention: version drift between the runner and the database, expiring credentials, silent failures, storage files, and the fact that nobody tests the restore.
Related reading: pg_dump + GitHub Actions: the free way, and the 5 things it misses
Method 5: A managed off-site backup
A managed service runs the schedule, captures the database along with storage objects, auth data, and Edge Functions, and writes the result to a location you own.
Supakeep does exactly this: scheduled backups delivered into your own Google Drive, with a zero-retention architecture, so the copies live somewhere separate from the provider that hosts production.
Choosing a method
| Manual pg_dump | Supabase PITR | GitHub Actions | Managed off-site | |
|---|---|---|---|---|
| Runs without you remembering | ||||
| Stored outside Supabase | ||||
| Covers storage files | rarely | |||
| Survives an account problem | ||||
| Setup effort | low | low | high | low |
| Ongoing maintenance | every run | none | ongoing | none |
How often should you run it?
The right frequency comes from one question: how much recent data can the business afford to lose? That number is your recovery point objective.
Daily is a sensible baseline for a small application. If your users create meaningful records every hour, go more frequent.
Test the restore
A backup nobody has restored is a hypothesis. At least once a quarter, take the most recent file, restore it into an empty project or a local PostgreSQL instance, and check that the app boots, users can sign in, and recent records are present.
Time the exercise. The number you get is your real recovery time, and it is usually longer than the one you assumed.
Related reading: Supabase backup best practices for small teams, Why every Supabase project needs its own backups, and The shared responsibility model: what your provider won't back up.
Sources & further reading
- 1Database backups]([Supabase Docssupabase.com
- 2Point-in-Time Recovery]([Supabase Docssupabase.com
- 3db dump]([Supabase CLI referencesupabase.com
- 4pg_dump]([PostgreSQL Documentationpostgresql.org
- 5Continuous Archiving and Point-in-Time Recovery]([PostgreSQL Documentationpostgresql.org
- 6Scheduled workflow events]([GitHub Docsdocs.github.com