Skip to main content
Prisma Documentation Docs

Search documentation

Type to search this documentation.

On this pageOverview

Local Postgres

Prisma Postgres is a hosted database for your staging and production environments. For local iteration and isolated testing, you can run a local Prisma Postgres instance (powered by PGlite) with the prisma dev command. This page explains how to launch and manage a local Prisma Postgres database.

Follow these steps to set up local Prisma Postgres for development.

Node.js v20 or later is required for local Prisma Postgres.

Navigate into your project and start the local Prisma Postgres server using the following command:

bunx prisma dev
Bash
pnpm prisma dev
Bash
yarn prisma dev
Bash
npx prisma dev

This starts a local Prisma Postgres server that you can connect to using Prisma ORM or another tool. The output of the command looks like this:

text
$ npx prisma dev
Loaded Prisma config from prisma.config.ts.

✔  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&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"
   SHADOW_DATABASE_URL="postgres://postgres:postgres@localhost:51215/template1?sslmode=disable&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"

🐘 You can also use the DATABASE_URL with the pg or postgres.js JavaScript drivers as well as your favorite DB gui.

   For the best experience, set the maximum number of connections to 10, connect timeout to 0 and
   idle timeout to the smallest positive value supported.

🌊 Prisma Streams is available at:

   PRISMA_STREAM_URL="http://127.0.0.1:51216/v1/stream/prisma-wal"

┌─────────────────┐
│ Press q to quit │
└─────────────────┘

You may:

  • q to quit

If you want to connect via Prisma ORM, hit h on your keyboard and copy both DATABASE_URL and SHADOW_DATABASE_URL into your .env file. Prisma ORM connects through the first one. Prisma Migrate uses the second one as the shadow database when it checks for drift. Without it, the first prisma migrate dev run works but later runs fail with a relation "..." already exists error.

.env
DATABASE_URL="postgres://postgres:postgres@localhost:51214/template1?sslmode=disable&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"
SHADOW_DATABASE_URL="postgres://postgres:postgres@localhost:51215/template1?sslmode=disable&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"

Then point the datasource block of your Prisma config at both variables:

prisma.config.ts
import "dotenv/config";
import { defineConfig } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: process.env["DATABASE_URL"],
    shadowDatabaseUrl: process.env["SHADOW_DATABASE_URL"],
  },
});

Keep the local Prisma Postgres server running in the background while you work on your application.

Alternatively, you can run the server in detached mode to free up your terminal:

This starts a local Prisma Postgres server that you can connect to using Prisma ORM or another tool. The output of the command looks like this:

$ npx prisma dev

Loaded Prisma config from prisma.config.ts.

✔  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&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"

   SHADOW_DATABASE_URL="postgres://postgres:postgres@localhost:51215/template1?sslmode=disable&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"

🐘 You can also use the DATABASE_URL with the pg or postgres.js JavaScript drivers as well as your favorite DB gui.

   For the best experience, set the maximum number of connections to 10, connect timeout to 0 and

   idle timeout to the smallest positive value supported.

🌊 Prisma Streams is available at:

   PRISMA_STREAM_URL="http://127.0.0.1:51216/v1/stream/prisma-wal"

┌─────────────────┐

│ Press q to quit │

└─────────────────┘

You may:

  • q to quit

If you want to connect via Prisma ORM, hit h on your keyboard and copy both DATABASE_URL and SHADOW_DATABASE_URL into your .env file. Prisma ORM connects through the first one. Prisma Migrate uses the second one as the shadow database when it checks for drift. Without it, the first prisma migrate dev run works but later runs fail with a relation "..." already exists error.

title=".env"
DATABASE_URL="postgres://postgres:postgres@localhost:51214/template1?sslmode=disable&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"

SHADOW_DATABASE_URL="postgres://postgres:postgres@localhost:51215/template1?sslmode=disable&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0"

Then point the datasource block of your Prisma config at both variables:

title="prisma.config.ts"
import "dotenv/config";

import { defineConfig } from "prisma/config";

export default defineConfig({

  schema: "prisma/schema.prisma",

  migrations: {

    path: "prisma/migrations",

  },

  datasource: {

    url: process.env["DATABASE_URL"],

    shadowDatabaseUrl: process.env["SHADOW_DATABASE_URL"],

  },

});

Keep the local Prisma Postgres server running in the background while you work on your application.

Alternatively, you can run the server in detached mode to free up your terminal:

title="bun"
bunx prisma dev --detach
pnpm
pnpm prisma dev --detach
yarn
yarn prisma dev --detach
npm
npx prisma dev --detach

This starts the server in the background. Use prisma dev ls to see running servers and prisma dev stop to stop them.

Then in a separate terminal tab, run the prisma migrate dev command to create the database and run the migrations:

bunx prisma migrate dev
Bash
pnpm prisma migrate dev
Bash
yarn prisma migrate dev
Bash
npx prisma migrate dev

[!NOTE] Make sure the local Prisma Postgres server is running before running the prisma migrate dev command.

If you must use a different port, append --port <number> (for example, npx prisma migrate dev --port 5422) and update your DATABASE_URL (or other connection settings) to match.

[!NOTE] If the first prisma migrate dev run against a fresh instance fails with Error: P1017 Server has closed the connection before it creates any tables, you have hit prisma/orm#29366: the query that reads the _prisma_migrations table drops the connection when that table does not exist yet. Create the table yourself, then run the command again:

create-migrations-table.sql
CREATE TABLE "_prisma_migrations" (
    "id"                  VARCHAR(36)  PRIMARY KEY NOT NULL,
    "checksum"            VARCHAR(64)  NOT NULL,
    "finished_at"         TIMESTAMPTZ,
    "migration_name"      VARCHAR(255) NOT NULL,
    "logs"                TEXT,
    "rolled_back_at"      TIMESTAMPTZ,
    "started_at"          TIMESTAMPTZ  NOT NULL DEFAULT now(),
    "applied_steps_count" INTEGER      NOT NULL DEFAULT 0
);

bun

```bash
bunx prisma db execute --file create-migrations-table.sql
```

pnpm

```bash
pnpm prisma db execute --file create-migrations-table.sql
```

yarn

```bash
yarn prisma db execute --file create-migrations-table.sql
```

npm

```bash
npx prisma db execute --file create-migrations-table.sql
```

prisma db push does not read that table, so it works as an alternative if you do not need migration files yet.

This will create the database and run the migrations.

If you have a seeder script to seed the database, you should also run it in this step.

This will create the database and run the migrations.

If you have a seeder script to seed the database, you should also run it in this step.

Start your application's development server. You can now perform queries against the local Prisma Postgres instance using Prisma ORM.

To transition to production, you only need to update the database URL in the .env file with a Prisma Postgres connection url without additional application logic changes.

You can target a specific, local Prisma Postgres instance via the --name (-n) option of the prisma dev command, for example:

bunx prisma dev --name="mydb1"
Bash
pnpm prisma dev start <glob>
Bash
yarn prisma dev start <glob>
Bash
npx prisma dev start <glob>

[!NOTE] The dev start command only works with instances that already exist.

<glob> is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be started, for example:

Whenever you pass the --name="mydb1" to prisma dev, the command will return the same connection string pointing to a local instance called mydb1. This creates a named instance that you can later manage using the instance management commands.

You can start existing Prisma Postgres instances in the background using:

bunx prisma dev start <glob>
Bash
pnpm prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)
Bash
yarn prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)
Bash
npx prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)

To start all databases that begin with mydb (e.g. mydb-dev and mydb-prod), you can use a glob:

<glob> is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be started, for example:

bunx prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)
Bash
pnpm prisma dev start mydb* # starts all existing DBs starting with `mydb`
Bash
yarn prisma dev start mydb* # starts all existing DBs starting with `mydb`
Bash
npx prisma dev start mydb* # starts all existing DBs starting with `mydb`

Use this command to start instances in the background without the VS Code extension.

To start all databases that begin with mydb (e.g. mydb-dev and mydb-prod), you can use a glob:

bunx prisma dev start mydb* # starts all existing DBs starting with `mydb`
Bash
pnpm prisma dev ls
Bash
yarn prisma dev ls
Bash
npx prisma dev ls

This command lists all available instances on your system, showing their current status and configuration.

Use this command to start instances in the background without the VS Code extension.

You can view all your local Prisma Postgres instances using:

bunx prisma dev ls
Bash
pnpm prisma dev stop <glob>
Bash
yarn prisma dev stop <glob>
Bash
npx prisma dev stop <glob>

<glob> is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be stopped, for example:

This command lists all available instances on your system, showing their current status and configuration.

You can stop a running Prisma Postgres instance with this command:

bunx prisma dev stop <glob>
Bash
pnpm prisma dev stop mydb # stops a DB called `mydb`
Bash
yarn prisma dev stop mydb # stops a DB called `mydb`
Bash
npx prisma dev stop mydb # stops a DB called `mydb`

To stop all databases that begin with mydb (e.g. mydb-dev and mydb-prod), you can use a glob:

<glob> is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be stopped, for example:

bunx prisma dev stop mydb # stops a DB called `mydb`
Bash
pnpm prisma dev stop mydb* # stops all DBs starting with `mydb`
Bash
yarn prisma dev stop mydb* # stops all DBs starting with `mydb`
Bash
npx prisma dev stop mydb* # stops all DBs starting with `mydb`

[!NOTE] The stop command is interactive and includes safety prompts to prevent accidental operations. You'll be asked to confirm the action by typing a confirmation phrase.

To stop all databases that begin with mydb (e.g. mydb-dev and mydb-prod), you can use a glob:

bunx prisma dev stop mydb* # stops all DBs starting with `mydb`
Bash
pnpm prisma dev rm <glob>
Bash
yarn prisma dev rm <glob>
Bash
npx prisma dev rm <glob>

<glob> is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be removed, for example:

Prisma Postgres saves the information and data from your local Prisma Postgres instances on your file system. To remove any trace from a database that's not in use any more, you can run the following command:

bunx prisma dev rm <glob>
Bash
pnpm prisma dev rm mydb # removes a DB called `mydb`
Bash
yarn prisma dev rm mydb # removes a DB called `mydb`
Bash
npx prisma dev rm mydb # removes a DB called `mydb`

To remove all databases that begin with mydb (e.g. mydb-dev and mydb-prod), you can use a glob:

<glob> is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be removed, for example:

bunx prisma dev rm mydb # removes a DB called `mydb`
Bash
pnpm prisma dev rm mydb* # removes all DBs starting with `mydb`
Bash
yarn prisma dev rm mydb* # removes all DBs starting with `mydb`
Bash
npx prisma dev rm mydb* # removes all DBs starting with `mydb`

You can use the --force flag to stop any running servers before removing them:

To remove all databases that begin with mydb (e.g. mydb-dev and mydb-prod), you can use a glob:

bunx prisma dev rm mydb* # removes all DBs starting with `mydb`
Bash
pnpm prisma dev rm mydb --force
Bash
yarn prisma dev rm mydb --force
Bash
npx prisma dev rm mydb --force

Without --force, the command will fail if any server is still running.

[!NOTE] The rm command is interactive and includes safety prompts to prevent accidental data loss. You'll be asked to confirm the action by typing a confirmation phrase that hints at the risks involved.

You can use the --force flag to stop any running servers before removing them:

bunx prisma dev rm mydb --force
Bash
pnpm prisma dev rm <name>
Bash
yarn prisma dev rm <name>
Bash
npx prisma dev rm <name>

Note that rm deletes the instance's stored data along with the leftover lock.

Without --force, the command will fail if any server is still running.

Local Prisma Postgres supports direct PostgreSQL connections, allowing you to connect to it via any tool.

In order to connect to your local Prisma Postgres instance, use the postgres:// connection string that's returned by prisma dev.

The Prisma VS Code extension has a dedicated UI managing Prisma Postgres instances.

To use it, install the VS Code extension and find the Prisma logo in the activity bar of your VS Code editor. It enables the following workflows:

  • creating and deleting databases
  • starting and stopping the server for a particular database
  • "push to cloud": move a database from local to remote

You can start and stop a local Prisma Postgres server from Node.js without invoking the CLI. This uses undocumented, unstable APIs from @prisma/dev and may change without notice. Use it at your own risk. It's especially useful for integration tests that need an ephemeral local database per test or suite.

This is a complete runnable example that will print [{abba: 1}] when run:

import { Client } from "pg";

import { startPrismaDevServer } from "@prisma/dev";

async function startLocalPrisma(name: string) {

  return await startPrismaDevServer({

    name, // required, use a unique name if running tests in parallel

    port: 51213, // optional, defaults to 51213

    databasePort: 51214, // optional, defaults to 51214

    shadowDatabasePort: 51215, // optional, defaults to 51215

    persistenceMode: "stateless", // optional, defaults to 'stateless'. Use 'stateful' to persist data between runs

  });

}

// Usage in tests

const server = await startLocalPrisma(`my-tests-${Date.now()}`);

try {

  const client = new Client({

    connectionString: server.database.connectionString,

  });

  await client.connect();

  const res = await client.query(`SELECT 1 as "abba"`);

  console.log(res.rows);

  client.end();

} finally {

  await server.close!();

}

The startPrismaDevServer() function accepts the following options:

Argument Required Description Default
name ❌ Unique identifier for the local Prisma Postgres instance. Use distinct names if running multiple servers in parallel. 'default'
port ❌ Port for the Prisma engine server. Throws an error if the port is already in use. 51213
databasePort ❌ Port for the embedded PostgreSQL database. Used for all Prisma ORM connections. 51214
shadowDatabasePort ❌ Port for the shadow database used during migrations. 51215
persistenceMode ❌ Defines how data is persisted:
• 'stateless': no data is retained between runs
• 'stateful': data persists locally
'stateless'
debug ❌ Whether to enable debug logging. false
dryRun ❌ Whether to run the server in dry run mode. false
databaseConnectTimeoutMillis ❌ Connection timeout in milliseconds for pending database connections. Starts ticking for every new client that attempts to connect. When exceeded, the pending client connection is evicted and closed. Use with caution, as it may lead to unexpected behavior. Best used with a pool client that retries connections. 60000 (1 minute)
databaseIdleTimeoutMillis ❌ Idle timeout in milliseconds for active database connections. Re-starts ticking after each message received on the active connection. When exceeded, the active client connection is closed, and a pending connection is promoted to active. Use with caution, as it may lead to unexpected disconnections. Best used with a pool client that can handle disconnections gracefully. Set it if you suffer from client hanging indefinitely. Not applied by default
shadowDatabaseConnectTimeoutMillis ❌ Connection timeout in milliseconds for pending shadow database connections. Defaults to databaseConnectTimeoutMillis
shadowDatabaseIdleTimeoutMillis ❌ Idle timeout in milliseconds for active shadow database connections. Defaults to databaseIdleTimeoutMillis

Notes:

  • Allocate unique ports and name values when running tests concurrently.
  • Use server.database.connectionString to connect with Postgres clients or ORMs.
  • Use this pattern for tests that require a local database.

Starting an instance may fail with A Prisma Dev server with the name <name> is already running, while npx prisma dev ls reports that same instance as not_running. This happens when a previous run of the server crashed or was force-killed and left its lock file behind: the start command saw only the held lock, while ls checked whether the server was actually alive.

Recent versions of prisma detect that the previous owner is dead, take over the leftover lock, and start normally. Projects whose installed prisma predates the fix can still hit this. Tools that embed the local server (such as Prisma Composer) run the @prisma/dev version installed in your project, so the fix reaches you by updating the project's prisma dependency.

To recover on an affected version, remove the stuck instance and start it again:

bunx prisma dev rm <name>

Note that rm deletes the instance's stored data along with the leftover lock.

The local Prisma Postgres database server accepts one connection at a time. Additional connection attempts queue until the active connection closes. This constraint is sufficient for most local development and testing scenarios.

The local Prisma Postgres server doesn't use HTTPS. We advise against self-hosting it.

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu