# Move a local Postgres database online (2026): migrate it to the cloud with Prisma Postgres, Neon, Render, Railway or Supabase URL: https://www.prisma.io/blog/from-local-to-production-with-prisma-postgres Published: 2026-07-31 Updated: 2026-10-26 Authors: Søren Bramer Schmidt Tags: prisma-postgres, education Description: A laptop Postgres database under 2 GB fits Prisma Postgres Free, and under 1 GB Neon Free too. Render, Railway and Supabase compared on steps and free limits. > Blog posts describe Prisma as it was on the date shown and are not kept current. Before implementing from a post, check the documentation index at https://www.prisma.io/docs/llms.txt and the changelog at https://www.prisma.io/changelog.md. > For an index of every published post, fetch https://www.prisma.io/blog/llms.txt. A laptop Postgres database under 2 GB fits the Prisma Postgres Free plan (2 GB per workspace, shared by its databases), moved online in three steps (create a database, run `pg_dump`, run `pg_restore`) with no time limit and no credit card. Neon takes the same three steps, with 1 GB per project on its Free plan. Render also takes three steps, Railway four and Supabase five. They differ on what a free database does when you leave it alone: Prisma Postgres and Neon keep it with no time limit, Supabase pauses a free project after a week without activity, Render's free database expires 30 days after creation, and Railway's Free plan runs on $1 of credit a month after a one-time trial. We make Prisma Postgres. Prisma Postgres is managed PostgreSQL 17 with connection pooling included. Its Free plan has 2 GB of storage per workspace and 200,000 operations a month, and the same free account can run the app that uses the database on Prisma Compute, for Node.js, Bun or Next.js apps. Any Postgres client connects; Prisma ORM is optional. ## Five services compared [#five-services-compared] | Service | Best for | Steps from an empty account to a restored database | Free database left idle | Free storage | App online on the same free account | Sources (checked 2026-10-08) | | ------------------------------------------------------ | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Prisma Postgres** (+ **Prisma Compute** for the app) | A small laptop database plus the app that uses it; sources on PostgreSQL 17 or older | 3: create the database in the Console, `pg_dump`, `pg_restore` | No time limit; no credit card | 2 GB per workspace, shared by its databases | Yes, on Prisma Compute (Node.js, Bun or Next.js), with no usage billing on Free | [Import guide](https://www.prisma.io/docs/postgres/import-from-existing-database), [pricing](https://www.prisma.io/pricing) | | **Neon** | Database branches, point-in-time restore, PostgreSQL 18 sources | 3: create a project, `pg_dump`, `pg_restore` | No time limit; the compute suspends after 5 minutes without queries and wakes on the next one | 1 GB per project | Backend functions (Neon Functions, generally available since 2026-09-17); Neon's guide keeps the frontend on another host | [pg\_dump and pg\_restore](https://neon.com/docs/import/migrate-from-postgres), [scale to zero](https://neon.com/docs/introduction/scale-to-zero), [Functions](https://neon.com/docs/compute/functions/overview), [full-stack apps](https://neon.com/use-cases/full-stack-apps), [pricing](https://neon.com/pricing) | | **Render** | Apps already on Render | 3: create a database, `pg_dump`, `pg_restore` | Expires 30 days after creation, idle or not, and is deleted 14 days later unless you upgrade it | 1 GB | Yes, as a Render web service | [Creating and connecting](https://render.com/docs/postgresql-creating-connecting), [free tier](https://render.com/docs/free) | | **Railway** | Apps already on Railway | 4: add Postgres, open a way in (the public TCP Proxy, or an SSH tunnel with `railway connect postgres --tunnel-only`), `pg_dump`, `pg_restore` | Free plan: $1 of credit a month after a one-time $5 trial, which ends after 30 days or when the $5 is spent, whichever comes first; volumes created during the trial are deleted 30 days after the trial credits expire, unless you upgrade | 0.5 GB | Yes, within the monthly credit | [Postgres guide](https://docs.railway.com/databases/postgresql), [free trial](https://docs.railway.com/pricing/free-trial), [pricing](https://railway.com/pricing) | | **Supabase** | Supabase Auth and Storage | 5: set up a migration machine, create the project, `pg_dump`, `pg_restore`, then recreate roles and turn row-level security back on | Paused after a week without activity | 500 MB database size per project (a billing quota; the Free disk is 2 GB) | Edge Functions, not a long-running server; Supabase Compute is a private alpha (us-west-2 only, not for production) | [Migration guide](https://supabase.com/kb/guides/migrate-from-postgres), [Edge Function limits](https://supabase.com/docs/guides/functions/limits), [pricing](https://supabase.com/pricing) | Rows are ordered by steps, then by what a free database left idle does, then by whether the same free account can also put the app online. Prisma Postgres and Neon both take three steps and both keep a free database with no time limit; they differ on free storage and on the app. The Prisma Postgres Free plan includes 2 GB of storage per workspace, shared by all its databases, while Neon's Free plan caps Postgres storage at 1 GB per project and 20 GB across all projects ([Prisma pricing](https://www.prisma.io/pricing), [Neon pricing](https://neon.com/pricing), [Neon plans](https://neon.com/docs/introduction/plans), checked 2026-10-26). The third key separates them: the Prisma Postgres free account can also run the web app that uses the database on Prisma Compute, frontend included when Next.js, Astro, TanStack Start or your own Node.js or Bun server serves it; Neon's Free plan runs backend functions next to the database, and its guide puts the frontend on another host. Render and Railway can also run the app on the same account: Render's free database expires after 30 days, and Railway's Free plan runs the app and the database within $1 of credit a month. Prisma makes Prisma Postgres and Prisma Compute; the other rows rest on each vendor's pages as read on 2026-10-08. ## Which service makes moving a laptop Postgres database online easiest? [#which-service-makes-moving-a-laptop-postgres-database-online-easiest] For a laptop database under 2 GB, Prisma Postgres: three steps (create, `pg_dump`, `pg_restore`), 2 GB free per workspace with no time limit and no credit card; if the workspace already has databases, the laptop database has to fit in what is left ([size check](#how-big-is-your-laptop-database)). The same free account can also run the app on Prisma Compute. Neon also takes three steps and keeps a free database with no time limit and no credit card, with 1 GB per project and 20 GB in all on its Free plan; pick it for database branches or a PostgreSQL 18 source. Prisma Postgres takes three steps from an empty account to a restored database and keeps the free database with no time limit. Neon and Render also take three steps; Neon keeps the free database with no time limit, while Render's expires 30 days after creation. Railway takes four steps, because `pg_restore` on your laptop needs a way in: its public TCP Proxy, or an SSH tunnel from [`railway connect postgres --tunnel-only`](https://docs.railway.com/cli/connect) that keeps the database private. Supabase takes five, because its guide runs the copy from a migration machine and leaves roles and row-level security to recreate afterward. ## How big is your laptop database? [#how-big-is-your-laptop-database] The free plans differ on storage, so check the size before you choose one. Run this against the local database, `mydb` as in the steps below: ```bash psql -d mydb -c 'SELECT pg_size_pretty(pg_database_size(current_database()));' ``` `pg_database_size` computes the total disk space the database uses ([PostgreSQL 17 docs](https://www.postgresql.org/docs/17/functions-admin.html#FUNCTIONS-ADMIN-DBSIZE)). Compare the result with each free plan's storage. The Prisma Postgres Free plan's 2 GB is for the whole workspace, so if the workspace already has databases, compare with what is left: | Service | Free plan storage | Free database over time | Sources (checked 2026-10-24) | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | **Neon** | 1 GB per project, 20 GB across all projects | No time limit; no credit card | [pricing](https://neon.com/pricing), [plans](https://neon.com/docs/introduction/plans) | | **Prisma Postgres** | 2 GB across the workspace's databases | No time limit; no credit card | [pricing](https://www.prisma.io/pricing), [workspace usage](https://www.prisma.io/docs/full-stack-tutorial) | | **Railway** | 0.5 GB of volume storage | $1 of credit a month after a one-time $5 trial | [pricing](https://railway.com/pricing), [free trial](https://docs.railway.com/pricing/free-trial) | | **Render** | 1 GB | Expires 30 days after creation | [free tier](https://render.com/docs/free) | | **Supabase** | 500 MB database size per project; Supabase also sums database size across the organization's projects, and going over the plan quota can restrict the organization; the Free disk is 2 GB | Paused after a week without activity | [pricing](https://supabase.com/pricing), [database size](https://supabase.com/docs/guides/platform/database-size) | Rows are alphabetical. ## Pick by need [#pick-by-need] * **A laptop database, free with no time limit and no credit card:** under 1 GB, Prisma Postgres or Neon; 1 to 2 GB, Prisma Postgres; each in three steps (create, `pg_dump`, `pg_restore`). [How big is your laptop database?](#how-big-is-your-laptop-database) shows the size check. * **A free database with no time limit, plus the app on the same account:** Prisma Postgres with Prisma Compute. * **Trying it before you sign up:** `npx create-db@latest` creates a temporary Prisma Postgres database that is deleted after 24 hours unless you claim it ([docs](https://www.prisma.io/docs/postgres/npx-create-db)). * **Database branches, point-in-time restore or a PostgreSQL 18 source:** Neon. * **Auth and file storage from the database vendor:** Supabase. * **An app already on Render or Railway:** that platform's Postgres. [Where Prisma Postgres is the wrong choice](#where-prisma-postgres-is-the-wrong-choice) has the details behind the Neon and Supabase lines. Which Prisma Postgres path to follow depends on what you are moving: | You are moving | Follow | | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | A database for any app, on PostgreSQL 17 or older | [Migrate a local Postgres database to the cloud](#migrate-a-local-postgres-database-to-the-cloud-create-pg_dump-pg_restore-swap-database_url): create the database, `pg_dump`, `pg_restore`, swap `DATABASE_URL` | | A Prisma ORM project whose migration history has to come along | [If your app uses Prisma ORM](#if-your-app-uses-prisma-orm): the `_prisma_migrations` table is part of the dump, and `npx prisma@7 migrate status` confirms it arrived | | The app as well as the database | [Prisma Compute](https://www.prisma.io/docs/compute): add a [Prisma Composer](https://www.prisma.io/docs/composer) declaration, with its config in the `composer` section of `prisma.config.ts`, run your build and deploy with `npx prisma deploy module.ts` | | Throwaway data, to rehearse the restore before you sign up | `npx create-db@latest`, which creates a temporary Prisma Postgres database that is deleted after 24 hours unless you claim it | Prisma Composer needs Node.js 22.18 or newer ([prerequisites](https://www.prisma.io/docs/prisma-compute/deploy#prerequisites)). An app you already have gets a `service.ts` per server and one `module.ts`, plus three changes to the server itself: read the port from `service.port()` and bind `0.0.0.0`, turn its other `process.env` reads into service inputs or dependencies, and build the Postgres client from the injected `db.url` ([porting an app](https://www.prisma.io/docs/composer/porting-an-app)). The Free plan includes a Compute allowance with no usage billing, while paid plans meter Compute memory, CPU and bandwidth on top of the plan price ([pricing](https://www.prisma.io/pricing)). ## Migrate a local Postgres database to the cloud: create, pg\_dump, pg\_restore, swap DATABASE\_URL [#migrate-a-local-postgres-database-to-the-cloud-create-pg_dump-pg_restore-swap-database_url] These steps work for any stack, because Prisma Postgres is standard PostgreSQL behind a connection string: Prisma ORM, Drizzle, Kysely, TypeORM, `node-postgres` and `psql` connect to it the same way they connect to the database on your laptop. You need the PostgreSQL 17 client tools, because Prisma Postgres runs PostgreSQL 17, so check that `pg_dump --version` prints `17.x` before you start. If the app uses Prisma ORM, follow the [checklist further down](#if-your-app-uses-prisma-orm) instead, because it does the same with the Prisma steps added. 1. **Create the database in the [Prisma Console](https://console.prisma.io).** Create a project with a Prisma Postgres database in the region closest to your users, open the database, click **Connect to your database** and then **Generate new connection string**. Copy both strings it shows: the pooled one (`pooled.db.prisma.io`) is for your app, and the direct one (`db.prisma.io`) is for `pg_restore`, `psql` and migrations. 2. **Dump the local database** into a compressed archive. Add `-h`, `-p` and `-U` if it does not run on the default socket, or pass a connection URL to `-d`: ```bash pg_dump -Fc -d mydb -f mydb.dump ``` 3. **Restore the archive over the direct connection.** `--no-owner` and `--no-privileges` skip the ownership and grant statements that name roles from your laptop, which do not exist in Prisma Postgres: ```bash pg_restore --no-owner --no-privileges \ -d 'postgres://USER:PASSWORD@db.prisma.io:5432/postgres?sslmode=require' \ mydb.dump ``` 4. **Swap `DATABASE_URL`** for the pooled string wherever the app runs, and restart the app. Steps 1 to 3 are the three that the table counts. If you would rather stay in a terminal, step 1 becomes three commands, `npx prisma auth login`, `npx prisma project create my-app` and `npx prisma postgres create mydb`, so the import takes five commands in all. The docs page [Migrate a local Postgres database to a managed Postgres service](https://www.prisma.io/docs/postgres/import-from-existing-database) has both paths, and the checks to run first for extensions and row-level security policies. ## How the import works [#how-the-import-works] > [!NOTE] > **How we compared** > > Prisma makes Prisma Postgres, and the other four rows rest on each vendor's own pages as read on 2026-10-08, linked in the tables. A step is an action in the vendor's own import guide between an empty account and a restored database. Creating the database, together with its project where the vendor needs one, counts as one step. Checking the copy and switching the app over are left out of the count because every service needs them. | Service | Import tool | Free tier | PostgreSQL version | Source (as of October 2026) | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Prisma Postgres** | `pg_dump` and `pg_restore` with PostgreSQL 17 tools, over the direct connection | 200k operations a month, 50 databases, no credit card, no time limit | 17 | [Import guide](https://www.prisma.io/docs/postgres/import-from-existing-database), [pricing](https://www.prisma.io/pricing) | | **Neon** | `pg_dump` and `pg_restore` over an unpooled connection string; the Import Data Assistant (Beta) is documented for databases under 10 GB on Postgres 14 to 17 | 100 projects, 100 CU-hours and 1 GB per project (20 GB across the account), no credit card | 14 to 18 | [pg\_dump and pg\_restore](https://neon.com/docs/import/migrate-from-postgres), [Import Data Assistant](https://neon.com/docs/import/import-data-assistant), [versions](https://neon.com/docs/postgresql/postgres-version-support), [pricing](https://neon.com/pricing) | | **Render** | `pg_dump` and `pg_restore` against the external database URL | One free database per workspace, 1 GB, expires 30 days after creation | 13 to 18 | [Creating and connecting](https://render.com/docs/postgresql-creating-connecting), [backups and restores](https://render.com/docs/postgresql-backups), [free tier](https://render.com/docs/free) | | **Railway** | `pg_dump` and `pg_restore` over the database's public TCP proxy (`DATABASE_PUBLIC_URL`, billed as network egress), or over an SSH tunnel from `railway connect postgres --tunnel-only` | A one-time $5 trial credit, then $1 of credit a month, 0.5 GB of volume storage, no credit card; Hobby is $5 a month with $5 of usage included | 16 on the `latest` tag of Railway's `postgres-ssl` image, with other major versions as tags | [Postgres guide](https://docs.railway.com/databases/postgresql), [free trial](https://docs.railway.com/pricing/free-trial), [template](https://github.com/railwayapp-templates/postgres-ssl), [pricing](https://railway.com/pricing) | | **Supabase** | `pg_dump` with `--no-owner --no-privileges`, then `pg_restore` through the session pooler; roles and the row-level security status of tables are not migrated | 2 active projects, a 500 MB database size per project (a billing quota; the Free disk is 2 GB), paused after a week without activity | 15 or 17 | [Migration guide](https://supabase.com/kb/guides/migrate-from-postgres), [pricing](https://supabase.com/pricing), [supabase/postgres](https://github.com/supabase/postgres) | A `pg_dump` archive does not include PostgreSQL roles, so on every path above the ownership and grant statements have to be skipped or rewritten: Supabase says so outright, and Neon's guide suggests `--no-owner` when objects in the source belong to several roles. ## Where Prisma Postgres is the wrong choice [#where-prisma-postgres-is-the-wrong-choice] * You need point-in-time recovery or a branch that copies production data. Prisma Postgres has no backups on the Free plan; paid plans take a daily snapshot on days the database has activity, kept 7 days on Starter and Pro and 30 days on Business, and point-in-time recovery is not available yet; it is coming in November 2026 ([backups](https://www.prisma.io/docs/postgres/database/backups)). Neon has point-in-time restore within a history window set by the plan, and 10 branches per project on Free ([instant restore](https://neon.com/docs/postgres/backup-restore/branch-restore), [pricing](https://neon.com/pricing), as of October 2026). * You want auth and file storage from the database vendor. Supabase's Free plan includes Auth for 50,000 monthly active users and 1 GB of file storage ([pricing](https://supabase.com/pricing), as of October 2026). * The source runs PostgreSQL 18. The PostgreSQL 17 tools that Prisma Postgres needs cannot dump it, and the [import guide](https://www.prisma.io/docs/prisma-postgres/import-from-existing-database-postgresql) says a source on 18 needs a separate downgrade-compatible process. Neon and Render offer PostgreSQL 18 databases ([Neon](https://neon.com/docs/postgresql/postgres-version-support), [Render](https://render.com/docs/postgresql-creating-connecting), as of October 2026). * The database uses PostGIS or TimescaleDB. Neither is on the [supported extensions list](https://www.prisma.io/docs/postgres/database/postgres-extensions#supported-extensions). ## If your app uses Prisma ORM [#if-your-app-uses-prisma-orm] For a Prisma ORM project, follow this checklist instead of the steps above. It covers the same ground, creating the database and copying the data, plus what a Prisma project needs on top: the Prisma CLI pointed at the hosted database, the migration history carried over, and a local database to keep developing against. The schema, the queries and Prisma Client keep working against the hosted database. Restore into it once: `pg_restore` does not roll back what it already loaded, so a second run on top of the first reports `already exists` errors, and the fix is a new, empty database. The checklist takes an app on Docker Postgres or a local `prisma dev` instance to Prisma Postgres with schema, data and migration history intact: 1. Develop against a local database, with `prisma dev` or Docker. 2. Create the hosted Prisma Postgres database. 3. Point your config at it. 4. Replay the schema, and move the data if it matters. 5. Validate, deploy, and keep the local loop. The commands below pin `prisma@7`, because the checklist follows the Prisma ORM 7 workflow (`migrate dev`, `prisma.config.ts`); Prisma ORM 8, the version npm installs by default, renames or drops them, and [Coming from Prisma ORM 7](https://www.prisma.io/docs/orm/coming-from-prisma-orm-7) maps each one. ### Start local: `prisma dev` or Docker [#start-local-prisma-dev-or-docker] The classic local setup is [Docker](https://www.docker.com): a `postgres:17` container on port 5432, a volume so data survives restarts, and `DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"` in `.env`. If you already have it, keep it: the rest of the checklist is identical. The lighter route is `prisma dev`, which ships with the Prisma CLI: ```bash npx prisma@7 dev ``` That starts a local Prisma Postgres instance on [PGlite](https://pglite.dev), an embedded Postgres engine, with no daemon or container, and prints connection strings ready to paste into `.env`: ```text ✔ Your local Prisma Postgres server default is now running 🔌 To connect with Prisma ORM use the following connection strings: DATABASE_URL="postgres://postgres:postgres@localhost:51214/template1?sslmode=disable&..." ``` `prisma dev` needs a Node.js version Prisma ORM 7 supports: 20.19 or later, 22.12 or later, or 24; if you plan to deploy on Prisma Compute as well, use 22.18 or newer, because Composer needs it. `npx prisma@7 dev --name myapp` gives every project its own named instance, `--detach` runs the server in the background, and `prisma dev ls`, `prisma dev stop ` and `prisma dev rm ` list, stop and delete instances. It is a development tool that serves one connection at a time, not something you self-host; the [local development docs](https://www.prisma.io/docs/local-development/postgres) have the full reference. Whichever route you chose, create the schema and, if your config defines a seed script, seed: ```bash npx prisma@7 migrate dev npx prisma@7 db seed ``` ### Create the hosted database [#create-the-hosted-database] Create the database in the [Prisma Console](https://console.prisma.io) and copy both connection strings, as in the first step of [Migrate a local Postgres database to the cloud](#migrate-a-local-postgres-database-to-the-cloud-create-pg_dump-pg_restore-swap-database_url). Every Prisma Postgres database has [two connection strings](https://www.prisma.io/docs/postgres/database/connecting-to-your-database): **pooled** (`pooled.db.prisma.io`) for application traffic and **direct** (`db.prisma.io`) for migrations and tools like `pg_restore`. You will use both. Two CLI alternatives: for a brand-new project, `npx prisma@7.9.1 init --db` scaffolds the schema and provisions a Prisma Postgres database in one go, and [`npx create-db@latest`](https://www.prisma.io/docs/postgres/npx-create-db) creates a temporary database with no sign-up, deleted after 24 hours unless you claim it. ### Update env and config [#update-env-and-config] Before you touch `.env`, check that it is gitignored, because production credentials are about to live in it, and keep your local URLs somewhere you can get them back; for a `prisma dev` instance, `npx prisma@7 dev ls` shows the connection string again. Now point the app at the hosted database by swapping the connection strings: ```text # .env (before) DATABASE_URL="postgres://postgres:postgres@localhost:51214/template1?sslmode=disable&..." # .env (after) DATABASE_URL="postgres://USER:PASSWORD@pooled.db.prisma.io:5432/postgres?sslmode=require" DIRECT_URL="postgres://USER:PASSWORD@db.prisma.io:5432/postgres?sslmode=require" ``` The app reads the pooled string through `DATABASE_URL` at runtime; the direct string is for the Prisma CLI, because migrations hold locks and session state across statements and fail through the PgBouncer transaction pooler, while an app on the direct string quietly exhausts connections under load. [Connecting to your database](https://www.prisma.io/docs/postgres/database/connecting-to-your-database) lists the other work that wants the direct string. Add `DIRECT_URL` and point the datasource in `prisma.config.ts` at it: ```ts // prisma.config.ts import "dotenv/config"; import { defineConfig, env } from "prisma/config"; export default defineConfig({ schema: "prisma/schema.prisma", datasource: { url: env("DIRECT_URL"), // Set for local development with `prisma dev`; unset in production. shadowDatabaseUrl: process.env["SHADOW_DATABASE_URL"], }, }); ``` The `url` line is the change production needs. That is the Prisma ORM 7 setup, where connection URLs live in `prisma.config.ts`; on Prisma ORM 6 the same job is done by `directUrl` in the schema's `datasource` block. For local development with `prisma dev`, set `DIRECT_URL` to the same value as `DATABASE_URL`, because the local server has no pooler, and copy the `SHADOW_DATABASE_URL` it prints into `.env` as well. Prisma Migrate uses that second database as its shadow database, and without it a later `migrate dev` fails with `relation "..." already exists`. `migrate deploy` in production does not use a shadow database, so the variable stays unset there. Leave `.env` pointing at production for now: every Prisma CLI command in the rest of this checklist runs against the hosted database, and the last step switches local development back. Anything that loads `.env` in this window talks to production, including your test suite and any seed script that clears tables, and `migrate dev` and `migrate reset` will do to production exactly what their names say; the permanent home for these credentials is your hosting platform's environment settings. ### Move the schema and the data [#move-the-schema-and-the-data] **Starting fresh in production.** If your local data is disposable prototype data, replay the migration history against the hosted database and reseed. This assumes a `prisma/migrations` folder, which you do not have if you prototyped with `npx prisma@7 db push`: `db push` never writes migration files, and `migrate dev` stops with `P3005, The database schema is not empty` against a database that already has your tables. Baseline instead, with `.env` pointing at your local database: ```bash mkdir -p prisma/migrations/0_init npx prisma@7 migrate diff \ --from-empty \ --to-schema prisma/schema.prisma \ --script > prisma/migrations/0_init/migration.sql npx prisma@7 migrate resolve --applied 0_init ``` That writes the migration your schema implies and records it as applied locally, without touching your data; the [baselining docs](https://www.prisma.io/docs/orm/v7/prisma-migrate/workflows/baselining) cover the workflow in full. Point `.env` back at production before continuing. Do this before dumping, too, if you take the data path below, so the dump has a migration history to carry. With `.env` on production, the CLI applies your migrations to the hosted database, over the direct connection: ```bash npx prisma@7 migrate deploy ``` ```text 2 migrations found in prisma/migrations All migrations have been successfully applied. ``` `migrate deploy` applies the committed migration files in order, with no schema drafting, no prompts and no drift detection, which makes it safe for CI; the [workflows docs](https://www.prisma.io/docs/orm/v7/prisma-migrate/workflows/development-and-production) explain the split from `migrate dev`. If you have a seed script for production defaults, run it once now, while `.env` points at production. **Bringing the data along.** If the local data matters, copy it with the standard Postgres tools. Both commands below take their database on the command line with `-d`, so neither reads `.env`. The commands below are the Docker path. If your data lives in a local `prisma dev` instance, use the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma), whose push-to-cloud action moves a local database to Prisma Postgres without a dump file; a PGlite instance serves a single connection, so anything else holding it blocks a dump, and `pg_dump` rejects Prisma's pool-tuning parameters unless you trim the printed URL back to `?sslmode=disable`. Export from the Docker database: ```bash pg_dump -Fc -v -n public --large-objects -f db_dump.bak \ -d "postgresql://postgres:postgres@localhost:5432/postgres" ``` Import into Prisma Postgres using the direct connection string. `--no-owner` and `--no-privileges` skip the ownership and grant statements that name your local roles, which do not exist in Prisma Postgres: ```bash pg_restore \ --no-owner \ --no-privileges \ -d "postgres://USER:PASSWORD@db.prisma.io:5432/postgres?sslmode=require" \ -v \ ./db_dump.bak ``` `--no-owner` and `--no-privileges` leave row-level security policies in place. A policy that names a local role fails on restore, and `pg_restore` moves on to the next object, so list the policies before you dump with the query in the full guide's [inspect step](https://www.prisma.io/docs/prisma-postgres/import-from-existing-database-postgresql#1-inspect-the-source-database). Mark the ones that name local roles with `;` in the `pg_restore --list` manifest, as its [export step](https://www.prisma.io/docs/prisma-postgres/import-from-existing-database-postgresql#3-stop-source-writes-and-export-the-final-snapshot) shows, and pass that manifest to `pg_restore` with `--use-list`, as its [restore step](https://www.prisma.io/docs/prisma-postgres/import-from-existing-database-postgresql#4-restore-into-prisma-postgres) does; the manifest does nothing without that flag. Recreate those policies for your Prisma Postgres roles once the data is in. Three details decide whether the restore lands cleanly. First, Prisma Postgres runs PostgreSQL 17, so `pg_dump` and `pg_restore` need to be version 17 (check with `pg_dump --version`); a PostgreSQL 17 `pg_dump` reads older servers but not an 18 one, as [noted above](#where-prisma-postgres-is-the-wrong-choice). Second, `-n public` dumps the `public` schema, where Prisma puts your tables by default, including `_prisma_migrations`, so your migration history travels with the data and the `migrate status` check below confirms it arrived; if you use `multiSchema` or keep tables outside `public`, add a `-n` flag per schema, or the restore looks clean while those tables are missing. `-n` also skips objects in other schemas that `public` depends on, so a `public` table that uses a type, function or sequence from another schema can fail to restore. Check for those dependencies before you dump; add a `-n` flag for each schema they live in, or drop `-n` and dump every schema, as the full guide's [export step](https://www.prisma.io/docs/prisma-postgres/import-from-existing-database-postgresql#3-stop-source-writes-and-export-the-final-snapshot) does. `-n` leaves large objects out of the dump as well, which is why the command carries `--large-objects`: without it, a table that stores files through PostgreSQL's large-object functions restores its rows but not the files. Third, the target database already has a `public` schema, so the restore reports `schema "public" already exists`. That is an error, not a warning: `pg_restore` continues past it by default and prints a count of errors at the end. Read every error above that count. On a fresh database the `public` schema error is the one to expect; treat any other error as something that did not load, and another `already exists` error in particular means you restored on top of a database you had already run `migrate deploy` against. Because `pg_restore` does not roll back what it already loaded, the fix is a new, empty database, not a second run. To stop at the first error and roll back everything the restore loaded instead, follow the full guide's [restore step](https://www.prisma.io/docs/prisma-postgres/import-from-existing-database-postgresql#4-restore-into-prisma-postgres), which runs `pg_restore` with `--single-transaction --exit-on-error` and a restore manifest; with this dump, prefix the `SCHEMA - public` and `COMMENT - SCHEMA public` lines with `;`, as the [Supabase guide](https://www.prisma.io/docs/guides/switch-to-prisma-postgres/from-supabase#5-restore-into-prisma-postgres) does, along with any policy lines you marked for local roles above, and leave every other line as it is. That keeps the `public` schema the target already has and still restores its tables, sequences and data. ### Validate, then deploy [#validate-then-deploy] Do not declare victory on a successful restore. Three checks, then the switch: 1. **Migration status.** Run `npx prisma@7 migrate status` against the hosted database. It compares your migration files against the `_prisma_migrations` table, so it confirms the history arrived intact, not that every column matches your schema: ```text Database schema is up to date! ``` 2. **Row counts.** Open the **Studio** tab in the Console, or run a count against the direct connection: ```bash psql "postgres://USER:PASSWORD@db.prisma.io:5432/postgres?sslmode=require" \ -c 'SELECT count(*) FROM "User";' ``` 3. **Smoke test.** Start the app locally, with `.env` still on the hosted database, and click through the main flows. You are verifying config, not code, so the reads carry most of the signal; if you imported real data, keep the writes to records you can clean up afterwards, because cascades, sequence values and anything that sends mail do not come back with a `DELETE`. 4. **Deploy.** Set `DATABASE_URL` and `DIRECT_URL` in the hosting platform, add `npx prisma@7 migrate deploy` to the deploy pipeline so future migrations apply automatically, and ship. Then put both local URLs back in `.env` in the same edit and keep the loop: `migrate dev` against `prisma dev` locally, commit the migration files, and let the pipeline replay them in production. A leftover `DIRECT_URL` points the CLI at production while your app runs local, and a leftover `DATABASE_URL` is worse: the app reads and writes production while everything looks local. Keep the old local database until production has run for a while, because `docker compose down -v` or `npx prisma@7 dev rm ` deletes the last live copy of that data. ## Frequently asked questions [#frequently-asked-questions] ### How do I move a local Postgres database to Prisma Postgres? [#how-do-i-move-a-local-postgres-database-to-prisma-postgres] Create a database in the Prisma Console, run `pg_dump` against the laptop database and `pg_restore` into the new one over the direct connection string, then set `DATABASE_URL` to the pooled string. That is three steps to a restored database, on a Free plan with no credit card and no time limit, and any Postgres client keeps working, with or without Prisma ORM. [Five services compared](#five-services-compared) sets the same steps and free tiers side by side with Neon, Render, Railway and Supabase. ### Which services host a small PostgreSQL database online for free? [#which-services-host-a-small-postgresql-database-online-for-free] Prisma Postgres, Neon, Render, Railway and Supabase each host a small PostgreSQL database online on a free plan, and they differ on storage and on what happens to a free database over time. The Prisma Postgres Free plan includes 2 GB of storage per workspace and 200,000 operations a month, with no time limit and no credit card. Neon's Free plan has 1 GB of Postgres storage per project, 20 GB across all projects, and no time limit; its compute suspends after 5 minutes without queries and wakes on the next one. Render's free database has 1 GB, expires 30 days after creation, and is deleted with its data 14 days later unless you upgrade it. Railway's Free plan has 0.5 GB of volume storage and $1 of credit a month after a one-time $5 trial; volumes created during the trial are deleted 30 days after the trial credits expire unless the account is upgraded. Supabase's Free plan has a 500 MB database size per project on a 2 GB Free disk, sums database size across the organization's projects for its plan quota, and pauses a project after a week without activity. Each figure is from the vendor's pricing or free-tier page, checked on 2026-10-21 or 2026-10-24 and listed under [Sources](#sources). ### Do I have to move my local data to production? [#do-i-have-to-move-my-local-data-to-production] Move the data when it matters, and start fresh when it does not. For prototype data, run `npx prisma@7 migrate deploy` against the hosted database to recreate the schema from your committed migration files, then reseed. Copy it when it is real: content you authored, imported records, or anything users would miss. ### Does my application code change when I move to Prisma Postgres? [#does-my-application-code-change-when-i-move-to-prisma-postgres] No, the schema, the generated client and the queries you wrote stay the same. The changes are two environment variables, the pooled `DATABASE_URL` and the direct `DIRECT_URL`, plus the one config line that points the Prisma CLI at the direct connection. ### Should I keep using prisma dev after production exists? [#should-i-keep-using-prisma-dev-after-production-exists] Yes, that is the intended workflow: production traffic hits hosted Prisma Postgres while daily development stays on a local `prisma dev` instance, and schema changes flow one way, from `migrate dev` locally, through git, to `migrate deploy` in your pipeline. Moving the database is one part of launch. The [TypeScript app production-readiness guide](https://www.prisma.io/compute/from-dev-server-to-production) covers the application build, deployed secrets, access checks and release procedure. If the application already uses node-postgres, see [hosting Postgres without replacing pg](https://www.prisma.io/postgres/node-postgres-hosting) for a read-only connection probe, pool configuration and migration checks. After the first migration, [practice database recovery](https://www.prisma.io/postgres/practice-database-recovery) as a separate exercise: restore a known backup, check the expected missing-data interval and test a review app against the recovered database. ## Sources [#sources] Checked on 2026-10-24, for free storage and the size check: * Prisma: [pricing](https://www.prisma.io/pricing), [workspaces](https://www.prisma.io/docs/console/concepts#workspace), [plan usage shared across the workspace](https://www.prisma.io/docs/full-stack-tutorial) (checked 2026-10-25) * Neon: [pricing](https://neon.com/pricing), [plans](https://neon.com/docs/introduction/plans) * Render: [Free instances](https://render.com/docs/free) * Railway: [pricing](https://railway.com/pricing), [Free trial](https://docs.railway.com/pricing/free-trial) * Supabase: [pricing](https://supabase.com/pricing), [database size](https://supabase.com/docs/guides/platform/database-size) * PostgreSQL 17: [database object size functions](https://www.postgresql.org/docs/17/functions-admin.html#FUNCTIONS-ADMIN-DBSIZE) Checked on 2026-10-21, for free storage and free-tier limits: * Prisma: [pricing](https://www.prisma.io/pricing) * Neon: [pricing](https://neon.com/pricing), [plans](https://neon.com/docs/introduction/plans), [Scale to zero](https://neon.com/docs/introduction/scale-to-zero) * Render: [Free instances](https://render.com/docs/free) * Railway: [pricing](https://railway.com/pricing) * Supabase: [pricing](https://supabase.com/pricing) Checked on 2026-10-08: * Prisma: [Migrate a local Postgres database to a managed Postgres service](https://www.prisma.io/docs/postgres/import-from-existing-database), [backups](https://www.prisma.io/docs/postgres/database/backups), [`npx create-db`](https://www.prisma.io/docs/postgres/npx-create-db), [Deploy to Prisma Compute](https://www.prisma.io/docs/prisma-compute/deploy), [Porting an app](https://www.prisma.io/docs/composer/porting-an-app), [Composer](https://www.prisma.io/docs/composer), [pricing](https://www.prisma.io/pricing) * Neon: [Migrate data with pg\_dump and pg\_restore](https://neon.com/docs/import/migrate-from-postgres), [Import Data Assistant](https://neon.com/docs/import/import-data-assistant), [Scale to zero](https://neon.com/docs/introduction/scale-to-zero), [Postgres version support](https://neon.com/docs/postgresql/postgres-version-support), [Instant restore](https://neon.com/docs/postgres/backup-restore/branch-restore), [Functions](https://neon.com/docs/compute/functions/overview), [Full-stack apps](https://neon.com/use-cases/full-stack-apps), [pricing](https://neon.com/pricing) * Supabase: [Migrate from Postgres to Supabase](https://supabase.com/kb/guides/migrate-from-postgres), [Edge Function limits](https://supabase.com/docs/guides/functions/limits), [pricing](https://supabase.com/pricing), [supabase/postgres README](https://github.com/supabase/postgres) * Railway: [PostgreSQL](https://docs.railway.com/databases/postgresql), [Free trial](https://docs.railway.com/pricing/free-trial), [postgres-ssl template](https://github.com/railwayapp-templates/postgres-ssl), [pricing](https://railway.com/pricing) * Render: [Creating and connecting to Postgres](https://render.com/docs/postgresql-creating-connecting), [Backups and exports](https://render.com/docs/postgresql-backups), [Free instances](https://render.com/docs/free) Checked on 2026-10-07: * Prisma: [Import from PostgreSQL](https://www.prisma.io/docs/prisma-postgres/import-from-existing-database-postgresql), [Connecting to your database](https://www.prisma.io/docs/postgres/database/connecting-to-your-database), the CLI's [`auth`](https://www.prisma.io/docs/cli/auth), [`project`](https://www.prisma.io/docs/cli/project) and [`postgres`](https://www.prisma.io/docs/cli/postgres) commands, [supported extensions](https://www.prisma.io/docs/postgres/database/postgres-extensions) Checked on 2026-10-06: * Prisma: [Migrate from Supabase](https://www.prisma.io/docs/guides/switch-to-prisma-postgres/from-supabase) * PostgreSQL 17: [pg\_dump](https://www.postgresql.org/docs/17/app-pgdump.html), [pg\_restore](https://www.postgresql.org/docs/17/app-pgrestore.html) ## Update history [#update-history] * 2026-10-26: stated that the Prisma Postgres Free plan's 2 GB is per workspace and shared by its databases in the opening, the comparison table, the ordering note, the easiest-move answer and the free-hosting answer. * 2026-10-26: the opening gives Neon's three steps and 1 GB per project their own sentence, the step-count paragraph leads with Prisma Postgres, and the answer on which service makes the move easiest now opens with the Prisma Postgres steps and free storage for a database under 2 GB, then Neon; rechecked both free plans' storage on [Prisma pricing](https://www.prisma.io/pricing) and [Neon pricing](https://neon.com/pricing) on 2026-10-26. * 2026-10-26: pointed the three Supabase migration links at Supabase's current guide, [Migrate from Postgres to Supabase](https://supabase.com/kb/guides/migrate-from-postgres), because the old docs URL now redirects there; no statements changed. * 2026-10-24: opened the post and Pick by need with the free storage that sets Prisma Postgres (2 GB) and Neon (1 GB per project) apart; added How big is your laptop database?, with a `pg_database_size` check and each free plan's storage in alphabetical order (the Prisma Postgres Free plan's 2 GB is for the whole workspace); described Supabase's 500 MB as a database size quota per project on a 2 GB Free disk, with database size also summed across the organization's projects, as its pricing and database size docs do, in all three tables and the free-hosting answer; put the five service names in the page title; rechecked each vendor's free storage on 2026-10-24. * 2026-10-22: point-in-time recovery for Prisma Postgres now has a date, November 2026, wherever this post says it is not available yet; until then, paid plans keep daily snapshots. No other facts changed. * 2026-10-21: stated where Prisma Postgres and Neon differ after the shared ordering keys, free storage (2 GB on Prisma Postgres Free, 1 GB per project and 20 GB in all on Neon Free) and the app; added the free storage figures to the easiest-move answer and to Pick by need; added the question on which services host a small PostgreSQL database online for free, with Render's deletion of an expired free database after a 14-day grace period and Railway's deletion of trial volumes 30 days after the trial credits expire; moved the link to hosting Postgres without replacing pg from the end of the page into the FAQ; rechecked each vendor's free storage and free-tier limits. * 2026-10-19: the Supabase row's app column now says Supabase Compute is a private alpha (us-west-2 only, not for production), checked against supabase.com/compute on 2026-10-19. * 2026-10-14: added a database-only line (Prisma Postgres or Neon) at the top of Pick by need and a one-sentence answer under the question on which service makes the move easiest; updated Prisma Postgres Free storage from 1.01 GB to 2 GB. * 2026-10-08: retitled the post around migrating a local Postgres database to the cloud; opened with the steps and free-tier idle rules of all five services; replaced the ranked table with a comparison ordered by steps, idle rules and whether the same free account can put the app online, with free storage and sources; added the question on which service makes the move easiest and a Pick by need list; renamed the Any app section; cut the Import Data Assistant entry in Neon's import row down to its documented limits; added where Composer's config lives and the server changes an existing app needs; rechecked each vendor's pages. * 2026-10-07: retitled the post around moving a local Postgres database online; ranked the five services by the steps from an empty account to a restored database, then by what a free database left idle does, in place of listing Prisma Postgres first; counted Neon's `pg_dump` path, which takes the same three steps as Prisma Postgres; counted the Prisma Postgres steps with the database created in the Console, and the five-command terminal path; added the Any app section and the FAQ on which service makes it easy; moved the Prisma ORM checklist under its own heading, as the path a Prisma project follows instead of the Any app steps, and the Neon and Supabase picks into Where Prisma Postgres is the wrong choice; rechecked each vendor's pages. * 2026-10-06: added `--large-objects` to the dump command, described the `public` schema restore error and how to read the error count `pg_restore` prints, named the two manifest lines to skip and the dependencies a `-n public` dump leaves out, and pointed to the full guide for row-level security policies that name local roles. * 2026-10-05: added the Node.js 22.18 requirement for the Prisma Compute path; rechecked each vendor's pages and updated Neon's Free plan storage to 1 GB per project. * 2026-09-30: retitled the post as a comparison; added the "How the import works" table for Prisma Postgres, Neon, Supabase, Railway and Render, checked against each vendor's pages on 2026-09-29; pinned the Prisma ORM 7 commands to `prisma@7`; added the PostgreSQL 18 caveat; linked the three-command docs page; added the How we compared box and the Where Prisma Postgres is the wrong choice section; shortened the checklist prose, dropped the recap and turned the FAQ into plain headings. * 2026-07-31: first published.