Moving off SupaHost
Everything you need to take a project from SupaHost to Supabase Cloud, a self-hosted Supabase or plain Postgres: database dump, Storage files, functions, cron jobs, settings and the switch-over.
SupaHost runs the open-source Supabase stack, so your project is portable. Everything it holds can be downloaded in standard formats: the database as a pg_dump file and Storage as a .tar.gz. The steps below work whether you're moving to Supabase Cloud, your own self-hosted Supabase, or a plain Postgres host.
1. Make a list of what the project uses
Before you export, note down what lives outside the database, because a dump won't carry it:
| Item | Where to find it on SupaHost |
|---|---|
| Auth settings: Site URL, redirect URLs, sign-in options | Auth tab |
| OAuth providers and their client IDs | Auth tab. Client secrets are never shown again, so get them from each provider's console |
| Email templates | Auth tab → Auth emails |
| Edge Functions | Functions tab. Keep the source in git if you don't already |
| Function secrets | Not shown again after saving. Use your own copy |
| Cron jobs | Cron tab, or select jobname, schedule, command from cron.job; |
| Queues | Queues tab. Queue tables are in the database dump |
| Custom domains | Domains tab |
2. Export the database
On Backups, click Create pg_dump and download the .dump file within 24 hours. It contains your schemas, data, functions, triggers, RLS policies, Auth users with password hashes and identities, and Storage metadata. See Exporting your data.
On Business you can also run pg_dump yourself through the SSH tunnel; see SSH access and direct Postgres.
3. Export Storage files
On Backups, click Package files and download the .tar.gz. It holds every file plus buckets.json (bucket settings) and objects.json (object metadata).
4. Restore at the destination
Plain Postgres. Restore your own schemas, skipping Supabase roles:
pg_restore --no-owner --no-privileges --schema=public \
-d "$TARGET_DATABASE_URL" app-one-20261111-0930.dump
Supabase Cloud or self-hosted Supabase. The target already has the auth and storage schemas, so don't restore those wholesale. One approach for an empty target project is to load Auth users first, so foreign keys from your tables to auth.users resolve, then your own schema:
# 1. Auth users and their identities (data only; the tables already exist)
pg_restore --no-owner --data-only --schema=auth --table=users --table=identities \
-d "$TARGET_DATABASE_URL" app-one.dump
# 2. Your own schema and data
pg_restore --no-owner --schema=public -d "$TARGET_DATABASE_URL" app-one.dump
Triggers you created on auth.users, such as one that inserts a profile row for each new user, belong to the auth schema and aren't restored by step 2; re-create them afterwards. Read any errors pg_restore prints rather than ignoring them all. Supabase's own guide to backup and restore with the CLI covers the details for a Supabase target. For Auth users specifically, see Moving Auth users between projects.
Storage files. Create the buckets from buckets.json, then upload the files with supabase-js or the destination's tools. A small Node script for a Supabase target:
import { createClient } from '@supabase/supabase-js'
import { readFile } from 'node:fs/promises'
const target = createClient(process.env.TARGET_URL!, process.env.TARGET_SERVICE_ROLE_KEY!)
async function upload(bucket: string, path: string, localFile: string, contentType: string) {
const body = await readFile(localFile)
const { error } = await target.storage.from(bucket).upload(path, body, { contentType, upsert: true })
if (error) console.error(bucket, path, error.message)
}
Read objects.json to get each object's bucket, path and content type, then call upload for each.
5. Recreate what the dump didn't carry
Work through the list from step 1: Auth settings, OAuth providers (with new callback URLs at each provider), email templates, Edge Functions and their secrets, and cron jobs.
6. Switch your app over
- Freeze writes on SupaHost, or schedule a quiet window, so nothing is written after your export. See Freezing writes during a migration.
- Take a final export and restore it.
- Update your app's URL and keys.
- If you used a custom domain, point its DNS at the new host. Apps that call your custom domain then follow without a new release.
- Tell users they may need to sign in again. The new host has a different JWT secret, so existing sessions won't carry over.
7. Close down on SupaHost
Once you've checked the new setup:
- Delete projects you no longer need from Settings → Danger zone. Deleting stops a project and archives its database.
- To close the instance, use Terminate on the Instance page. This sends a termination request by email.
- To close your SupaHost account, use Delete account in Settings. It's a request that you confirm by email.
Questions about any step, or about your final invoice, go to [email protected].