Importing from Supabase Cloud
Copy a Supabase Cloud project into SupaHost in one step: database, Auth users with passwords, RLS policies, roles, Storage buckets and files. Requirements and what to redo afterwards.
The importer copies a Supabase Cloud project into an empty SupaHost project. It brings over the database, Auth users with their passwords and identities, RLS policies and roles, and Storage buckets with their files. Your users keep their passwords, and your app keeps working once you point it at the new URL and keys.
What you need
- An empty SupaHost project to import into, already running. "Empty" means 0 Auth users, 0 tables in
publicand 0 Storage objects. Create a fresh one on Projects → New project. - The Session pooler connection string for your Supabase Cloud project.
- A secret key for the Supabase Cloud project, if you want Storage files copied.
You need to be the SupaHost owner to run an import.
The Session pooler string
In the Supabase dashboard, open Connect and copy the Session pooler connection string. It looks like this:
postgresql://postgres.abcdefghijklmnopqrst:[YOUR-PASSWORD]@aws-0-eu-west-2.pooler.supabase.com:5432/postgres
Check three things: the host ends in .pooler.supabase.com, the port is 5432, and the user is postgres. followed by your 20-character project ref. Replace [YOUR-PASSWORD] with your database password.
Two common strings are rejected:
- The direct connection (
db.<ref>.supabase.co). It's IPv6 only, and the importer can't reach it. - The transaction pooler on port 6543. A full copy needs a session connection.
The secret key
For Storage files, paste either a secret key (sb_secret_...) or the legacy service_role key from your Supabase Cloud project's API settings. Publishable and anon keys are rejected. The importer tests the key against the Storage API before it starts.
Run the import
- Open your empty project, then go to the Import tab, or use the "…" menu → Import from Supabase Cloud.
- Paste the Session pooler string and the secret key.
- Start the import and follow the phases: Connect → Copy from Supabase → Restore → Storage files → Done.
The owner gets an email when it's done, or if it fails. The import stops if it runs longer than 8 hours.
What's copied
| Copied | Details |
|---|---|
| Database | Schemas, tables, data, functions, triggers, roles and grants. Replayed in one transaction, so if the database step fails, nothing is left half-imported |
| RLS policies | Including triggers and policies you added on the auth and storage schemas |
| Auth users | With password hashes and linked identities (Google, GitHub and so on) |
| Storage | Buckets, and every file with its owner and timestamps. Files are copied 6 at a time, with up to 3 attempts each |
Extensions that SupaHost doesn't have are skipped, with a warning.
What isn't copied
The importer lists these for you at the end. Redo each one by hand:
| Not copied | What to do |
|---|---|
| Auth settings (Site URL, redirect URLs) and OAuth provider keys | Re-enter them on the Auth tab. See Site URL and redirect URLs |
| Edge Functions | Deploy them from the Functions tab or with an AI agent over MCP. See Deploying functions |
| pg_cron jobs | Re-create them with cron.schedule |
| Vault secrets | Add them again. Function secrets go on the Functions tab's Secrets card |
To move cron jobs, list them on Supabase Cloud first:
select jobname, schedule, command from cron.job;
Then create each one in the SupaHost project, without create extension pg_cron, which isn't needed here:
select cron.schedule(
'nightly-invoice-reminders',
'0 7 * * *',
$$ select public.send_invoice_reminders() $$
);
After the import
- Update your app's settings with the new project URL and keys from the Connect tab:
SUPABASE_URL=https://app-one.acme.supahost.space
SUPABASE_ANON_KEY=<anon key from Connect>
SUPABASE_SERVICE_ROLE_KEY=<service_role key, server only>
- Update OAuth callback URLs at each provider to
https://app-one.acme.supahost.space/auth/v1/callback, or your custom domain's callback once it's active. See Custom domains. - Expect one sign-in per user. Each project has its own JWT secret, so sessions issued by Supabase Cloud aren't valid here. Users sign in once more with the same password or provider; nothing else changes for them.
- Keep writes on the old project to a minimum between the import and the switch, or plan a short freeze. Anything written to Supabase Cloud after the import started isn't copied. See Freezing writes during a migration.
How credentials are handled
Your connection string and key are stored in Vault, then handed to your instance as a secret that only that VM can read. The secret is deleted when the import ends. Change your Supabase Cloud database password afterwards if you'd like to be sure nothing can reuse it.