# 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.

Source: https://supahost.app/docs/platform/leaving-supahost · Updated 2026-11-11

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](/docs/platform/exports).

On Business you can also run `pg_dump` yourself through the SSH tunnel; see [SSH access and direct Postgres](/docs/platform/ssh).

## 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:

```bash
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:

```bash
# 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](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore) covers the details for a Supabase target. For Auth users specifically, see [Moving Auth users between projects](/kb/migrate-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:

```ts
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

1. Freeze writes on SupaHost, or schedule a quiet window, so nothing is written after your export. See [Freezing writes during a migration](/kb/read-only-mode).
2. Take a final export and restore it.
3. Update your app's URL and keys.
4. 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.
5. 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 supahost@volods.com.

## Related

- [Exporting your data](/docs/platform/exports)
- [Data protection and privacy](/docs/security/data-protection)
- [Is SupaHost real Supabase?](/kb/is-it-really-supabase)
