All posts
How-toDec 17, 2025·8 min read·Supakeep Team

How to restore a Supabase project from a SQL backup

A step-by-step walkthrough of restoring a .sql.gz backup into a new or existing Supabase project — including troubleshooting, verification, and audit documentation.

How to restore a Supabase project from a SQL backup

When You Need This Guide

Your production database is gone. Maybe a migration went wrong. Maybe someone ran DROP TABLE. Maybe your Supabase project was deleted. You have a .sql.gz backup in your Google Drive from Supakeep. Now what?

This guide walks through the full restore process — from downloading the backup to verifying the restored data to documenting the test for compliance.

Source: [Supabase Docs — Backup and Restore using the CLI](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore)


Prerequisites

Before you start, you need:

  1. 1A .sql.gz backup file (from Supakeep's Google Drive folder)
  2. 2A fresh Supabase project (create one in the dashboard — never restore to production)
  3. 3The psql command-line tool installed locally
  4. 4Your new project's connection string (found in Dashboard > Settings > Database)

Step 1: Download the Backup

Backup folder structure (Google Drive):

  supabackups/
    |__ db_2026-07-30.sql.gz      <- Database dump
    |__ storage_2026-07-30.tar     <- Storage objects
    |__ auth_2026-w30.json.gz      <- Auth data
    |__ edge_2026-w30.zip          <- Edge functions

Download the db_*.sql.gz file for the date you want to restore to. If you also have storage and auth backups, download those too — you'll need them for a complete restore.


Step 2: Create a Fresh Supabase Project

Never restore to your production database. Always create a new project for testing.

  1. 1Go to https://supabase.com/dashboard
  2. 2Click "New Project"
  3. 3Choose a name like restore-test-2026-07
  4. 4Select the same region as your original project
  5. 5Set a strong database password
  6. 6Wait for the project to provision (2-3 minutes)

Step 3: Decompress and Restore

# Decompress the backup
gunzip db_2026-07-30.sql.gz

# Restore to the new project
psql "postgresql://postgres:YOUR_PASSWORD@db.YOUR_REF.supabase.co:5432/postgres" \
  -f db_2026-07-30.sql
Restore output:

  SET
  CREATE TABLE
  CREATE TABLE
  ALTER TABLE
  COPY 10000
  COPY 5000
  CREATE INDEX
  ...
  (no errors = success)

If you see COPY X lines with numbers, data is being inserted. If you see errors, check the troubleshooting section below.


Step 4: Restore Storage Objects (If Applicable)

If your backup includes a storage_*.tar file, you need to upload the files back to your new project's storage buckets:

# Extract storage archive
tar -xf storage_2026-07-30.tar

# Upload files via the Supabase Storage API
# (Use the Supabase CLI or SDK for this step)

This step is only needed if your app uses Supabase Storage for user uploads. Without this, storage URLs will return 404.


Step 5: Verify the Restore

-- Check table row counts
SELECT 'users' as table, count(*) FROM users
UNION ALL
SELECT 'posts', count(*) FROM posts
UNION ALL
SELECT 'orders', count(*) FROM orders;

-- Check RLS policies are intact
SELECT tablename, policyname, cmd 
FROM pg_policies 
WHERE schemaname = 'public';

-- Check roles exist
SELECT rolname FROM pg_roles 
WHERE rolname IN ('anon', 'authenticated', 'service_role');

If all row counts match, RLS policies are present, and roles exist — your restore is successful.


Step 6: Document for Compliance

If you're restoring as part of a compliance audit (SOC 2, ISO 27001), document the test:

Restore Test Record

  Date:           2026-07-30
  Backup file:    db_2026-07-30.sql.gz
  Target project: restore-test-2026-07
  Result:         SUCCESS
  Rows restored:  17,500 (users: 10k, posts: 5k, orders: 2.5k)
  RLS policies:   3 verified intact
  Roles:         anon, authenticated, service_role present
  Verified by:   [Your name]

Screenshot the verification queries and attach to your audit evidence file. This is the documentation auditors look for.

Source: [Konfirmity — SOC 2 Backup And Recovery](https://www.konfirmity.com/blog/soc-2-backup-and-recovery-for-soc-2)


Troubleshooting

ErrorCauseSolution
permission denied for tableMissing role permissionsRecreate roles: CREATE ROLE anon; CREATE ROLE authenticated;
relation already existsTables exist in targetUse --clean flag or restore to empty project
role does not existRoles not in dumpManually create Supabase roles before restore
COPY failedData type mismatchCheck if backup was from a different Postgres version
syntax errorIncompatible Postgres versionUse the same or newer Postgres version for restore

Restore runbook at a glance
  1. 1

    Get a clean target

    Create a fresh Supabase project or reset the existing database.

  2. 2

    Fetch the dump

    Download the .sql backup and verify its size and checksum.

  3. 3

    Restore roles first

    Apply roles and grants before data so RLS policies attach correctly.

  4. 4

    Load schema and data

    Run psql against the connection string and watch for errors.

  5. 5

    Re-upload storage objects

    Database dumps only carry file metadata, not the files.

  6. 6

    Verify

    Spot-check row counts, sign in as a real user, and confirm RLS behaves.

A restore you have never tested is not a backup.

Related reading: Supabase backup best practices for small teams and pg_dump + GitHub Actions: the free way, and the 5 things it misses.

Frequently asked questions

It depends on database size. A small database (under 100MB) typically restores in 2-5 minutes. Larger databases (1GB+) can take 15-30 minutes or more. The `psql` command shows progress as it processes each table.

You can, but it's risky. Restoring to production can overwrite live data. Always restore to a fresh project first, verify the data, then switch your app's connection string if everything looks correct.

Standard pg_dump may not include global roles. You'll need to manually create Supabase's roles (anon, authenticated, service_role) before restoring data. Supakeep's auth backup artifact includes this information.

Yes. Database backups only contain metadata about storage objects, not the files themselves. If your app uses Supabase Storage, you need to restore both the database dump and the storage archive.

Run the restore to a test project, verify row counts and RLS policies with SQL queries, screenshot the results, and record the date, backup file, target project, and verification results. See Step 6 above for a template.

Check the troubleshooting table above. Common issues include missing roles, incompatible Postgres versions, and existing tables in the target project. Most errors have straightforward fixes documented in PostgreSQL's psql guide.

Sources & further reading

  1. 1Backup and Restore using the CLISupabase Docssupabase.com
  2. 2Database BackupsSupabase Docssupabase.com
  3. 3pg_dumpPostgreSQL Docspostgresql.org
  4. 4psqlPostgreSQL Docspostgresql.org
  5. 5SOC 2 Backup And RecoveryKonfirmitykonfirmity.com
  6. 6Annex A 8.13ISO 27001 Decodediso27001.com

Automate your Supabase backups today

Set it once in 20 seconds. Backups run on schedule straight to your own Google Drive.

Start free backup

Keep reading