Skip to content

How to Clone a Supabase Project: 5 Methods Compared

Published Jul 5, 2026 · 9 min read

There are five real ways to clone a Supabase project: the dashboard's "Restore to a new project" feature, a manual pg_dump/pg_restore, the Supabase CLI's supabase db dump, replaying your migration files into a new project, or a purpose-built tool like SupaClone. Which one is right depends on whether you need the data or just the structure, whether you're on a paid plan, and how much manual cleanup you're willing to do. This guide walks through each method with real commands and the failure modes the docs gloss over.

Supabase has no one-click "Duplicate project" button in the general case — the closest thing is backup restoration, and everything else is assembled from Postgres tooling. Each method below states upfront what it copies, what it silently skips, and when it's the wrong choice.

Can you clone a Supabase project from the dashboard?

Yes, if you're on a paid plan. Supabase's Restore to a new project feature takes a physical backup (or a PITR point) of your source project and spins up a brand-new project from it. It copies the full database — schema, data, indexes, roles, and even auth users with hashed passwords — plus some project settings like compute size and SSL enforcement.

The requirements and caveats:

  • Paid plan only, and physical backups must be enabled on the source. A common workaround from GitHub discussion #22066: temporarily enable PITR to force a physical backup, restore, then disable PITR again.
  • It's database-only. Storage files, Edge Functions, Auth configuration, API keys, and Realtime settings all need manual reconfiguration in the new project.
  • A cloned project can't be cloned again — restored projects can't serve as sources for further restores.
  • Extensions that reach outside the database (pg_cron, pg_net, wrappers) keep running in the clone. Disable them immediately after restore, or your staging clone will fire production webhooks.

When it's the right choice: you need a full copy including production data and you're on a paid plan. It's the only method here that brings auth users along. For a structure-only staging environment, it's heavyweight — you get all your production data in the clone, which may be exactly what your compliance team doesn't want.

How do you clone a Supabase project with pg_dump and pg_restore?

Since every Supabase project is a Postgres database, plain pg_dump works — up to a point. The naive version looks like this:

pg_dump "$SOURCE_DB_URL" --schema-only -f dump.sql
psql "$TARGET_DB_URL" -f dump.sql

Run that against a Supabase project and the restore drowns in errors, because a Supabase database is not a vanilla Postgres database. The dump includes Supabase-managed schemas (auth, storage, realtime, extensions) that already exist in the target with objects owned by supabase_admin — a role you don't have. The result is walls of:

ERROR:  permission denied for schema auth
ERROR:  must be owner of event trigger ...
ERROR:  relation "buckets" already exists

The developers in discussion #22066 hit exactly this: permission-denied errors on schemas, functions, and event triggers, hundreds of "already exists" conflicts, and foreign-key violations from restore ordering. The fixes are all manual: exclude managed schemas with --schema=public (and every other custom schema you own), comment out ALTER ... OWNER TO "supabase_admin" lines, and re-run until clean. We cover the full workflow, flag by flag, in our pg_dump/pg_restore with Supabase guide.

When it's the right choice: you're comfortable with Postgres tooling, you need fine-grained control (specific schemas, specific tables, custom filtering), or you're scripting something the CLI doesn't cover. Just budget time for the cleanup pass — and know that nothing verifies the result. If a trigger or RLS policy didn't make it, you find out in production.

How do you clone a Supabase project with the Supabase CLI?

The Supabase CLI is the officially supported middle ground. supabase db dump runs pg_dump in a container with Supabase-aware defaults: it excludes managed schemas (auth, storage, and extension-created schemas) automatically, and by default dumps neither data nor custom roles — those are separate, deliberate steps.

The official backup-and-restore workflow is three dumps and one restore:

supabase db dump --db-url "$SOURCE_DB_URL" -f roles.sql --role-only
supabase db dump --db-url "$SOURCE_DB_URL" -f schema.sql
supabase db dump --db-url "$SOURCE_DB_URL" -f data.sql --use-copy --data-only

psql --single-transaction --variable ON_ERROR_STOP=1 \
  --file roles.sql --file schema.sql \
  --command 'SET session_replication_role = replica' \
  --file data.sql --dbname "$TARGET_DB_URL"

(session_replication_role = replica disables triggers during data load so trigger-driven columns aren't double-processed.)

This is much better than raw pg_dump, but the docs themselves list the sharp edges:

  • Custom roles with LOGIN need their passwords set manually in the target — passwords aren't dumped.
  • You may still need to comment out ALTER ... OWNER TO "supabase_admin" lines in schema.sql.
  • If you customized the auth or storage schemas (custom triggers, extra columns), those changes are skipped by default — you have to diff and port them yourself.
  • Webhooks, non-default extensions, and Realtime publications must be enabled in the target before restoring.
  • Storage objects and Edge Functions aren't part of the database at all; they need separate SDK scripts, which we walk through in cloning Storage buckets and Edge Functions.

When it's the right choice: it's free, scriptable, and official. If you clone occasionally, don't mind a manual checklist, and want data included, this is a solid default. What it doesn't give you is verification — after psql exits, you're trusting that everything arrived.

Can you recreate a Supabase project from migration files?

If your team has kept a disciplined migration history — every schema change as a file in supabase/migrations/ — then the cleanest clone isn't a clone at all. You create a fresh project and replay history:

supabase link --project-ref <new-project-ref>
supabase db push

This is the workflow Supabase's own tooling is built around, and it's the backbone of a proper dev/staging/prod workflow. It's reproducible, reviewable in PRs, and free.

The catch is the word disciplined. Migrations only recreate what's in them. If anyone ever created a table in the dashboard, tweaked an RLS policy in the SQL editor, or added an index directly on prod, your migration history has drifted from reality — and db push recreates the history, not the database. Most real projects older than a few months have drift. You can detect it with supabase db diff --linked, but reconciling months of drift is often more work than any other method on this list.

When it's the right choice: greenfield projects and teams that enforce migrations-only changes from day one. If that's you, you don't need a cloning tool — keep doing what you're doing. If you're also weighing Supabase's branching feature for this, see branching vs separate projects.

How does SupaClone clone a Supabase project?

SupaClone exists for the common case the methods above leave rough: you have a real production project (with drift, with dashboard-made changes) and you want its structure in a fresh project — for staging, for a dev sandbox, for a client handoff — without babysitting dump files.

You connect both projects via Supabase OAuth (no connection strings to copy around), pick a fresh, empty target project, and SupaClone runs native pg_dump/pg_restore under the hood with a baseline-aware plan that correctly skips the Supabase-managed schemas (auth, storage, realtime) — the exact thing that produces the permission-denied walls in the manual approach. It clones schemas, tables, RLS policies, functions, triggers, indexes, views, enums, and extensions. Optional add-ons cover Storage buckets/files, Edge Functions, and Auth configuration.

Two things distinguish it from a script:

  1. Verification. Every run ends with a field-by-field comparison of source and target and a full report: what was cloned, what was skipped, what failed, and which manual steps remain. This is the step every other method lacks — with the CLI or pg_dump, a silently missing RLS policy (see copying RLS policies between projects) is invisible until it's an incident.
  2. Secrets are never copied. Edge Function secrets and auth provider credentials show up as explicit manual steps in the report instead of being silently dropped or, worse, silently duplicated into staging.

Honest limits: SupaClone clones structure only today — data clones (exact and anonymized) and scheduled clones are coming soon but not shipped. It only writes into fresh, empty targets and only reads the source, so it can't sync into an existing project. Pricing is $7/month, $70/year, or $84 lifetime, each with a 14-day free trial that includes one successful clone.

When it's the right choice: structure-first clones from a drifted production project, especially recurring ones — the typical staging environment setup. If you need production data in the clone today, use the dashboard restore or the CLI workflow instead.

Which method should you use to clone a Supabase project?

Dashboard restoreManual pg_dumpSupabase CLIMigrations replaySupaClone
Copies dataYesOptionalOptionalNoComing soon
Copies auth usersYesNo (managed schema)NoNoNo
Handles managed schemasAutomaticManual exclusionAutomaticN/AAutomatic (baseline-aware)
RLS policiesYesYes, unverifiedYes, unverifiedOnly if in migrationsYes, verified
Storage / Edge FunctionsManualManualManual scriptsManualOptional add-ons
Verification reportNoNoNoNoYes, field-by-field
Handles schema driftYesYesYesNoYes
RequirementsPaid plan + physical backupsPostgres skillsCLI + checklistClean migration history$7/mo after trial

Rules of thumb:

  • Need data + auth users, on a paid plan? Dashboard restore.
  • Clean migration history, no drift? Replay migrations — it's free and reproducible.
  • One-off clone, comfortable with Postgres, want data? Supabase CLI workflow.
  • Structure-only clone from a real, drifted project — and proof it worked? SupaClone.
  • Maximum control over exactly what's dumped? Manual pg_dump, eyes open.

FAQ

Does Supabase have a built-in way to clone a project?

Yes — "Restore to a new project" in the dashboard, which restores a physical backup into a brand-new project. It requires a paid plan with physical backups enabled, copies the database only (Storage files, Edge Functions, and Auth config need manual setup), and a restored project can't be used as a source for further clones.

Why does pg_dump/pg_restore fail on Supabase projects?

Because dumps include Supabase-managed schemas (auth, storage, realtime) whose objects are owned by supabase_admin, a superuser-like role you can't act as. Restoring produces permission-denied and already-exists errors. Fix it by excluding managed schemas from the dump (or using supabase db dump, which does that by default) and stripping ALTER ... OWNER TO "supabase_admin" statements.

Does cloning a Supabase project copy the auth users?

Only the dashboard's "Restore to a new project" does, since it restores a physical backup including the auth schema with hashed passwords. Every other method — CLI, pg_dump, migrations, SupaClone — skips the managed auth schema, so users are not copied.

Can I clone a Supabase project into an existing project?

Generally no, and you shouldn't try. Restores into non-empty projects cause object conflicts and partial failures. The dashboard restore always creates a new project, and SupaClone requires a fresh, empty target by design. For syncing changes into an existing project, use migrations and supabase db push instead.

Is there a free way to clone a Supabase project?

Yes: supabase db dump plus psql, or replaying your migration files into a new project, both cost nothing beyond the new project itself. The dashboard restore requires a paid plan; SupaClone is paid but includes one successful clone in its 14-day trial.

Clone your Supabase project without the pg_dump pitfalls

SupaClone copies schemas, tables, RLS policies, functions, and triggers into a fresh project — verified after every run. 14-day free trial, 1 clone included.

Start free trial