# Migrate from Render Postgres

> Move a Render Postgres database to SupaHost: dump it with the external connection string, restore it into a project, enable RLS and point your Render services at the Data API.

Source: https://supahost.app/kb/migrate-from-render · Updated 2026-11-11

A Render Postgres database moves to SupaHost with `pg_dump` and a restore. Render services that talk to Postgres directly will need to switch to the Data API (supabase-js or HTTP), because a SupaHost project's Postgres port isn't open to the internet. On Business and Enterprise you can restore over an SSH tunnel; on other plans you use one of the load paths below.

## Plan

- **Size and plan.** The database must fit the plan's shared quota (8 GB Builder, 25 GB Pro, 50 GB Business). Multi-gigabyte restores are simplest on Business.
- **Access.** In the Render dashboard, open the database and check **Access Control**: your machine's IP must be allowed for the external connection.
- **Downtime.** Suspend the services that write to the database before the final dump, or schedule a short maintenance window.

## Export from Render

Copy the **External Database URL** from the database's **Connect** menu, then:

```bash
pg_dump -Fc --no-owner --no-privileges -n public \
  "postgresql://invoices_user:<password>@dpg-abc123-a.frankfurt-postgres.render.com/invoices" \
  -f invoices.dump
```

Use pg_dump 17 (SupaHost runs Postgres 17). `--no-owner --no-privileges` drops Render's role names, which don't exist on SupaHost.

## Prepare the target

List the extensions the source uses:

```sql
select extname from pg_extension where extname <> 'plpgsql';
```

Create the same ones in your SupaHost project (Studio → SQL editor), in the `extensions` schema:

```sql
create extension if not exists citext with schema extensions;
```

## Load

**Business and Enterprise.** Add an SSH key in Dashboard → your project → **Connect** → **SSH & CLI**, then:

```bash
ssh -N -L 6543:127.0.0.1:5432 supahost@acme.supahost.space &
pg_restore --no-owner --no-privileges \
  -d "postgresql://postgres:<password>@127.0.0.1:6543/p_app_one" invoices.dump
```

**Builder and Pro.**

- For anything larger than a handful of tables, restore the dump into a temporary Supabase Cloud project and use the [one-click import](/kb/migrate-from-supabase-cloud).
- For small databases, generate the schema with `pg_restore --schema-only -f schema.sql invoices.dump`, run it in Studio's SQL editor or through MCP `apply_migration`, then import each table as CSV in the table editor. Export CSVs from Render with `\copy invoices to 'invoices.csv' csv header` in psql.

## After loading

```sql
alter table public.invoices enable row level security;
alter table public.customers enable row level security;
analyze;
```

Add policies for the rows each user may see. If you imported CSVs into tables with identity or serial columns, reset the sequences ([duplicate key after importing data](/kb/duplicate-key-sequence)).

## Switch the app

On Render, replace `DATABASE_URL` in each service's environment with:

```bash
SUPABASE_URL=https://app-one.acme.supahost.space
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOi...   # server-side only
```

Then move queries to supabase-js. A Render background worker that needs heavy SQL can call a database function with `supabase.rpc('close_month', { month: '2026-10' })`.

## Verify

Compare `select count(*)` for each important table, compare a few totals (for example `select sum(amount_cents) from invoices`), and keep the Render database until you're confident.

## Related

- [Importing data (CSV, SQL dumps)](/docs/database/import-data)
- [Operations too complex for the client library](/kb/complex-operations-rpc)
- [Use SupaHost from a Node.js server](/docs/getting-started/node-server)
- [Connecting directly to Postgres](/kb/direct-postgres-connection)
