Migrate from Supabase Cloud to SupaHost
Move a Supabase Cloud project to SupaHost with the one-click import: what you need, what gets copied, what you redo by hand, and how to switch your app.
SupaHost can copy a Supabase Cloud project for you. The import moves the database, Auth users (with their passwords and identities), RLS policies and roles, and Storage buckets and files. You redo a short list of settings by hand afterwards. This article walks through the whole move, from planning to switching your app over.
Plan the move
- Pick a quiet time. The import reads a snapshot of the source. Writes made to Supabase Cloud after it starts won't be copied, so freeze writes or accept a short gap (see Freezing writes during a migration).
- Check sizes. The database and files must fit your plan's shared quotas (Builder 8 GB database / 100 GB files, Pro 25 GB / 250 GB, Business 50 GB / 500 GB). Add-ons can raise them.
- Create an empty target project. The import only runs into a live project with 0 Auth users, 0 tables in
publicand 0 Storage objects. A fresh project from Projects → New project qualifies.
Collect two values from Supabase Cloud
The Session pooler connection string. In the Supabase dashboard, click Connect and copy the Session pooler string. It looks like this:
postgresql://postgres.abcdefghijklmnopqrst:[YOUR-PASSWORD]@aws-0-eu-central-1.pooler.supabase.com:5432/postgresPut your database password in place of
[YOUR-PASSWORD]. The directdb.<ref>.supabase.cohost is rejected (it's IPv6 only), and so is the transaction pooler on port 6543.A secret key for Storage. Either an
sb_secret_…key or the legacyservice_rolekey. Publishable and anon keys are rejected. SupaHost tests the key against the Storage API before it starts.
Run the import
- Dashboard → your new project → Import tab (also in the project's … menu as Import from Supabase Cloud).
- Paste the connection string and the key, then start the import.
- Watch the phases: Connect → Copy from Supabase → Restore → Storage files → Done. You get an email when it finishes or fails.
The schema, roles and data are replayed inside one transaction, so a database error rolls the whole copy back instead of leaving half the tables behind. Extensions that SupaHost doesn't have are skipped with a warning. Files copy six at a time with retries, and their owners and timestamps are kept. The job can run for up to 8 hours.
Redo what isn't copied
The import lists these items for you at the end:
| Not copied | Where to set it up on SupaHost |
|---|---|
| Site URL, redirect URLs, OAuth provider keys | Auth tab. Each provider's callback becomes https://app-one.acme.supahost.space/auth/v1/callback; update it in the provider's console too |
| Edge Functions | Functions tab, or deploy over MCP |
| pg_cron jobs | cron.schedule(...) in the SQL editor, or the Cron tab |
| Vault secrets | Re-create with vault.create_secret(...); function secrets go in the Functions tab's Secrets card |
Switch your app
Replace the URL and anon key in your app's environment (copy them from Connect → App):
SUPABASE_URL=https://app-one.acme.supahost.space
SUPABASE_ANON_KEY=eyJhbGciOi...
Every SupaHost project has its own JWT secret, so existing sessions don't carry over. Users sign in again once; their passwords still work.
Verify
select count(*) from auth.users;
select count(*) from storage.objects;
select relname, n_live_tup from pg_stat_user_tables order by n_live_tup desc;
Compare the counts with the same queries on Supabase Cloud, sign in with a test account, upload a file, and call each Edge Function once.