From 7a9174e09f52e35a43ccbdc00a4e3cb2cc43a1c3 Mon Sep 17 00:00:00 2001 From: Aman Varshney Date: Mon, 17 Nov 2025 16:32:52 +0530 Subject: [PATCH] Update docs to perform migrations with connection pooling and Prisma config --- .../500-databases/880-supabase.mdx | 40 +++++++++++------- .../050-overview/500-databases/890-neon.mdx | 38 +++++++++++------ .../200-pgbouncer.mdx | 36 +++++++++++----- .../050-databases-connections/index.mdx | 36 ++++++++++------ .../100-queries/037-relation-queries.mdx | 6 +-- .../150-using-raw-sql/100-typedsql.mdx | 2 +- .../301-edge/485-deploy-to-vercel.mdx | 8 ++-- .../050-prisma-client-reference.mdx | 2 +- .../300-accelerate/200-getting-started.mdx | 42 ++++++++++--------- 9 files changed, 129 insertions(+), 81 deletions(-) diff --git a/content/200-orm/050-overview/500-databases/880-supabase.mdx b/content/200-orm/050-overview/500-databases/880-supabase.mdx index b17558b8fa..6c3475a379 100644 --- a/content/200-orm/050-overview/500-databases/880-supabase.mdx +++ b/content/200-orm/050-overview/500-databases/880-supabase.mdx @@ -26,7 +26,7 @@ Many aspects of using Prisma ORM with Supabase are just like using Prisma ORM wi ## Specific considerations -If you'd like to use the [connection pooling feature](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pooling-in-depth) available with Supabase, you will need to use the connection pooling connection string available via your [Supabase database settings](https://supabase.com/dashboard/project/_/settings/database) with `?pgbouncer=true` appended to the end of your `DATABASE_URL` environment variable: +If you'd like to use the [connection pooling feature](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pooling-in-depth) available with Supabase, you will need to use the connection pooling connection string available via your [Supabase database settings](https://supabase.com/dashboard/project/_/settings/database) with `?pgbouncer=true` appended to the end of the environment variable that Prisma Client reads when you instantiate it with a driver adapter: ```env file=.env # Connect to Supabase via connection pooling with Supavisor. @@ -41,33 +41,41 @@ Supabase provides three types of connection strings for each database: 3. **Session Pooler Connection string** – `postgresql://postgres.[your-project-ref]:password@aws-0-[region].pooler.supabase.com:5432/postgres` -If you would like to use the Prisma CLI in order to perform other actions on your database (e.g. migrations), your setup depends on the connection string used: +Prisma CLI commands (for example, migrations and introspection) now read the direct, non-pooled connection string from `prisma.config.ts`. Configure two environment variables — the pooled connection string for Prisma Client (`DATABASE_URL`) and a direct connection string for the Prisma CLI (`DIRECT_URL`): -- If your `DATABASE_URL` uses the Transaction Pooler (connection string 2), you must provide a `DIRECT_URL` with either the Direct Database (1) or Session Pooler (3) connection string in order for Prisma Migrate to work. - -- If your `DATABASE_URL` already uses the Session Pooler (connection string 3), you do not need to provide a `DIRECT_URL`. Prisma Migrate will work without it. - -```env file=.env highlight=4-5;add showLineNumbers +```env file=.env highlight=5-7;add showLineNumbers # Connect to Supabase via connection pooling with Supavisor. DATABASE_URL="postgres://postgres.[your-supabase-project]:[password]@aws-0-[aws-region].pooler.supabase.com:6543/postgres?pgbouncer=true" -//add-start -# Direct connection to the database. Used for migrations. +# Direct connection to the database used by the Prisma CLI. DIRECT_URL="postgres://postgres.[your-supabase-project]:[password]@aws-0-[aws-region].pooler.supabase.com:5432/postgres" # or DIRECT_URL="postgresql://postgres:password@db.[your-project-ref].supabase.co:5432/postgres" -//add-end ``` -You can then update your `schema.prisma` to use the new direct URL: +Point `prisma.config.ts` to the direct connection string: + +```ts file=prisma.config.ts showLineNumbers +import 'dotenv/config' +import { defineConfig, env } from 'prisma/config' -```prisma file=schema.prisma highlight=4;add showLineNumbers -datasource db { - provider = "postgresql" -} +export default defineConfig({ + schema: 'prisma/schema.prisma', + datasource: { + url: env('DIRECT_URL'), + }, +}) ``` -More information about the `directUrl` field can be found [here](/orm/reference/prisma-schema-reference#fields). +At runtime, instantiate Prisma Client with a driver adapter using the pooled `DATABASE_URL`. This keeps the direct connection string scoped to Prisma CLI workflows while your application connections continue to flow through Supavisor. + +```ts file=src/db/client.ts showLineNumbers +import { PrismaClient } from '../prisma/generated/client' +import { PrismaPg } from '@prisma/adapter-pg' + +const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }) +export const prisma = new PrismaClient({ adapter }) +``` :::info diff --git a/content/200-orm/050-overview/500-databases/890-neon.mdx b/content/200-orm/050-overview/500-databases/890-neon.mdx index 046bc1674d..114faeef54 100644 --- a/content/200-orm/050-overview/500-databases/890-neon.mdx +++ b/content/200-orm/050-overview/500-databases/890-neon.mdx @@ -39,34 +39,46 @@ There are a few differences between Neon and PostgreSQL you should be aware of t ## How to use Neon's connection pooling If you would like to use the [connection pooling](https://neon.tech/docs/guides/prisma#use-connection-pooling-with-prisma) available in Neon, you will -need to add `-pooler` in the hostname of your `DATABASE_URL` environment variable used in the `url` property of the `datasource` block of your Prisma schema: +need to add `-pooler` in the hostname of the connection string that Prisma Client uses via a driver adapter: ```bash file=.env # Connect to Neon with Pooling. DATABASE_URL=postgres://daniel:@ep-mute-rain-952417-pooler.us-east-2.aws.neon.tech:5432/neondb?sslmode=require ``` -If you would like to use Prisma CLI in order to perform other actions on your database (e.g. for migrations) you will need to add a `DIRECT_URL` environment variable to use in the `directUrl` property of the `datasource` block of your Prisma schema so that the CLI will use a direct connection string (without PgBouncer): +Prisma CLI commands (for example, `prisma migrate` or `prisma db pull`) now read the direct connection string from `prisma.config.ts`. Configure both a pooled and non-pooled environment variable: -```env file=.env highlight=4-5;add showLineNumbers -# Connect to Neon with Pooling. +```env file=.env highlight=5-6;add showLineNumbers +# Connect to Neon with pooling (used by Prisma Client via the adapter). DATABASE_URL=postgres://daniel:@ep-mute-rain-952417-pooler.us-east-2.aws.neon.tech/neondb?sslmode=require -//add-start -# Direct connection to the database used by Prisma CLI for e.g. migrations. +# Direct connection to the database used by the Prisma CLI. DIRECT_URL="postgres://daniel:@ep-mute-rain-952417.us-east-2.aws.neon.tech/neondb" -//add-end ``` -You can then update your `schema.prisma` to use the new direct URL: +Point `prisma.config.ts` to the direct connection string: + +```ts file=prisma.config.ts showLineNumbers +import 'dotenv/config' +import { defineConfig, env } from 'prisma/config' -```prisma file=schema.prisma highlight=4;add showLineNumbers -datasource db { - provider = "postgresql" -} +export default defineConfig({ + schema: 'prisma/schema.prisma', + datasource: { + url: env('DIRECT_URL'), + }, +}) ``` -More information about the `directUrl` field can be found [here](/orm/reference/prisma-schema-reference#fields). +At runtime, instantiate Prisma Client with the pooled connection string using `@prisma/adapter-neon`: + +```ts file=src/db/client.ts showLineNumbers +import { PrismaClient } from '../prisma/generated/client' +import { PrismaNeon } from '@prisma/adapter-neon' + +const adapter = new PrismaNeon({ connectionString: process.env.DATABASE_URL }) +export const prisma = new PrismaClient({ adapter }) +``` :::info diff --git a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/200-pgbouncer.mdx b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/200-pgbouncer.mdx index 744c8a3b3a..1c562d8504 100644 --- a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/200-pgbouncer.mdx +++ b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/200-pgbouncer.mdx @@ -65,21 +65,37 @@ Error: undefined: Database error Error querying the database: db error: ERROR: prepared statement "s0" already exists ``` -To work around this issue, you must connect directly to the database rather than going through PgBouncer. To achieve this, you can use the [`directUrl`](/orm/reference/prisma-schema-reference#fields) field in your [`datasource`](/orm/reference/prisma-schema-reference#datasource) block. +To work around this issue, configure a **direct** connection for Prisma CLI commands in `prisma.config.ts`, while Prisma Client continues to use the PgBouncer URL via a driver adapter. -For example, consider the following `datasource` block: +```env file=.env highlight=4-6;add showLineNumbers +# PgBouncer (pooled) connection string used by Prisma Client. +DATABASE_URL="postgres://USER:PASSWORD@HOST:PORT/DATABASE?pgbouncer=true" -```prisma -datasource db { - provider = "postgresql" - url = "postgres://USER:PASSWORD@HOST:PORT/DATABASE?pgbouncer=true" - directUrl = "postgres://USER:PASSWORD@HOST:PORT/DATABASE" -} +# Direct database connection string used by Prisma CLI. +DIRECT_URL="postgres://USER:PASSWORD@HOST:PORT/DATABASE" ``` -The block above uses a PgBouncer connection string as the primary URL using `url`, allowing Prisma Client to take advantage of the PgBouncer connection pooler. +```ts file=prisma.config.ts showLineNumbers +import 'dotenv/config' +import { defineConfig, env } from 'prisma/config' -It also provides a connection string directly to the database, without PgBouncer, using the `directUrl` field. This connection string will be used when commands that require a single connection to the database, such as `prisma migrate dev` or `prisma db push`, are invoked. +export default defineConfig({ + schema: 'prisma/schema.prisma', + datasource: { + url: env('DIRECT_URL'), + }, +}) +``` + +```ts file=src/db/client.ts showLineNumbers +import { PrismaClient } from '../prisma/generated/client' +import { PrismaPg } from '@prisma/adapter-pg' + +const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }) +export const prisma = new PrismaClient({ adapter }) +``` + +With this setup, PgBouncer stays in the path for runtime traffic, while Prisma CLI commands (`prisma migrate dev`, `prisma db push`, `prisma db pull`, and so on) always use the direct connection string defined in `prisma.config.ts`. ### PgBouncer with different database providers diff --git a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx index d94e3e2e48..3dba249f14 100644 --- a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx +++ b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx @@ -336,29 +336,39 @@ datasource db { Connection poolers like [Prisma Accelerate](/accelerate) and PgBouncer prevent your application from exhausting the database's connection limit. -If you would like to use the Prisma CLI in order to perform other actions on your database ,e.g. migrations and introspection, you will need to add an environment variable that provides a direct connection to your database in the `datasource.directUrl` property in your Prisma schema: +To keep Prisma Client on the pooled connection while allowing Prisma CLI commands (for example, migrations or introspection) to connect directly, define two environment variables: -```env file=.env highlight=4,5;add showLineNumbers +```env file=.env highlight=4-6;add showLineNumbers # Connection URL to your database using PgBouncer. DATABASE_URL="postgres://root:password@127.0.0.1:54321/postgres?pgbouncer=true" -//add-start -# Direct connection URL to the database used for migrations +# Direct connection URL to the database used for Prisma CLI commands. DIRECT_URL="postgres://root:password@127.0.0.1:5432/postgres" -//add-end ``` -You can then update your `schema.prisma` to use the new direct URL: +Configure `prisma.config.ts` to point to the direct connection string. Prisma CLI commands always read from this configuration. -```prisma file=schema.prisma highlight=4;add showLineNumbers -datasource db { - provider = "postgresql" - //add-next-line - directUrl = env("DIRECT_URL") -} +```ts file=prisma.config.ts showLineNumbers +import 'dotenv/config' +import { defineConfig, env } from 'prisma/config' + +export default defineConfig({ + schema: 'prisma/schema.prisma', + datasource: { + url: env('DIRECT_URL'), + }, +}) ``` -More information about the `directUrl` field can be found [here](/orm/reference/prisma-schema-reference#fields). +At runtime, instantiate Prisma Client with a driver adapter (for example, `@prisma/adapter-pg`) that uses the pooled connection string: + +```ts file=src/db/client.ts showLineNumbers +import { PrismaClient } from '../prisma/generated/client' +import { PrismaPg } from '@prisma/adapter-pg' + +const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }) +export const prisma = new PrismaClient({ adapter }) +``` ### Prisma Accelerate diff --git a/content/200-orm/200-prisma-client/100-queries/037-relation-queries.mdx b/content/200-orm/200-prisma-client/100-queries/037-relation-queries.mdx index daffbf41a1..8764971718 100644 --- a/content/200-orm/200-prisma-client/100-queries/037-relation-queries.mdx +++ b/content/200-orm/200-prisma-client/100-queries/037-relation-queries.mdx @@ -530,7 +530,7 @@ const result = await prisma.user.create({ There are two ways to create or update a single record and multiple related records - for example, a user with multiple posts: -- Use a nested [`create`](/orm/reference/prisma-client-reference#create-1) query +- Use a nested [`create`](/orm/reference/prisma-client-reference#create) query - Use a nested [`createMany`](/orm/reference/prisma-client-reference#createmany-1) query In most cases, a nested `create` will be preferable unless the [`skipDuplicates` query option](/orm/reference/prisma-client-reference#nested-createmany-options) is required. Here's a quick table describing the differences between the two options: @@ -544,7 +544,7 @@ In most cases, a nested `create` will be preferable unless the [`skipDuplicates` #### Using nested `create` -The following query uses nested [`create`](/orm/reference/prisma-client-reference#create-1) to create: +The following query uses nested [`create`](/orm/reference/prisma-client-reference#create) to create: - One user - Two posts @@ -640,7 +640,7 @@ Here's a visual representation of how a nested create operation can write to sev #### Using nested `createMany` -The following query uses a nested [`createMany`](/orm/reference/prisma-client-reference#create-1) to create: +The following query uses a nested [`createMany`](/orm/reference/prisma-client-reference#createmany) to create: - One user - Two posts diff --git a/content/200-orm/200-prisma-client/150-using-raw-sql/100-typedsql.mdx b/content/200-orm/200-prisma-client/150-using-raw-sql/100-typedsql.mdx index ab961eb88d..27c7b506b6 100644 --- a/content/200-orm/200-prisma-client/150-using-raw-sql/100-typedsql.mdx +++ b/content/200-orm/200-prisma-client/150-using-raw-sql/100-typedsql.mdx @@ -244,7 +244,7 @@ TypedSQL does not work with MongoDB, as it is specifically designed for SQL data ### Active Database Connection Required -TypedSQL requires an active database connection to function properly. This means you need to have a running database instance that Prisma can connect to when generating the client with the `--sql` flag. If a `directUrl` is provided in your Prisma configuration, TypedSQL will use that for the connection. +TypedSQL requires an active database connection to function properly. This means you need to have a running database instance that Prisma can connect to when generating the client with the `--sql` flag. TypedSQL uses the connection string defined in `prisma.config.ts` (`datasource.url`) to establish this connection. ### Dynamic SQL Queries with Dynamic Columns diff --git a/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx b/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx index f5d06377d7..e1420e3cca 100644 --- a/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx +++ b/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx @@ -170,15 +170,14 @@ model User { If you are using Vercel Postgres, you need to: - use the `@prisma/adapter-neon` database adapter because Vercel Postgres uses [Neon](https://neon.tech/) under the hood -- be aware that Vercel by default calls the environment variable for the database connection string `POSTGRES_PRISMA_URL` while the default name used in the Prisma docs is typically `DATABASE_URL`; using Vercel's naming, you need to configure these in `prisma.config.ts`: +- be aware that Vercel by default calls the pooled connection string `POSTGRES_PRISMA_URL` while the direct, non-pooled connection string is exposed as `POSTGRES_URL_NON_POOLING`. Configure `prisma.config.ts` so that the Prisma CLI uses the direct connection string: ```ts file=prisma.config.ts import { defineConfig, env } from 'prisma/config' export default defineConfig({ schema: 'prisma/schema.prisma', datasource: { - url: env('POSTGRES_PRISMA_URL'), // uses connection pooling - directUrl: env('POSTGRES_URL_NON_POOLING'), // uses a direct connection + url: env('POSTGRES_URL_NON_POOLING'), // direct connection for Prisma CLI }, }) ``` @@ -211,8 +210,7 @@ import { defineConfig, env } from 'prisma/config' export default defineConfig({ schema: 'prisma/schema.prisma', datasource: { - url: env('POSTGRES_PRISMA_URL'), // uses connection pooling - directUrl: env('POSTGRES_URL_NON_POOLING'), // uses a direct connection + url: env('POSTGRES_URL_NON_POOLING'), // direct connection for Prisma CLI }, }) ``` diff --git a/content/200-orm/500-reference/050-prisma-client-reference.mdx b/content/200-orm/500-reference/050-prisma-client-reference.mdx index f92eadde2b..8ea2c2473f 100644 --- a/content/200-orm/500-reference/050-prisma-client-reference.mdx +++ b/content/200-orm/500-reference/050-prisma-client-reference.mdx @@ -825,7 +825,7 @@ const user = await prisma.user.findMany({ #### Remarks -- You can also perform a nested [`create`](#create-1) - for example, add a `User` and two `Post` records at the same time. +- You can also perform a nested [`create`](#create) - for example, add a `User` and two `Post` records at the same time. #### Examples diff --git a/content/300-accelerate/200-getting-started.mdx b/content/300-accelerate/200-getting-started.mdx index b06abc67a4..2401e0f1b3 100644 --- a/content/300-accelerate/200-getting-started.mdx +++ b/content/300-accelerate/200-getting-started.mdx @@ -41,14 +41,7 @@ DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=__API_KEY__" # DATABASE_URL="postgresql://user:password@host:port/db_name?schema=public" ``` -Your updated connection string will be used as the datasource `url` in your Prisma schema file; - -```prisma -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} -``` +Prisma Client reads the `prisma://` URL from `DATABASE_URL` at runtime, while Prisma CLI commands use the connection string defined in `prisma.config.ts`. Prisma Migrate and Introspection do not work with a `prisma://` connection string. In order to continue using these features add a new variable to the `.env` file named `DIRECT_DATABASE_URL` whose value is the direct database connection string: @@ -57,15 +50,18 @@ DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=__API_KEY__" DIRECT_DATABASE_URL="postgresql://user:password@host:port/db_name?schema=public" ``` -Then in your Prisma schema's `datasource` block add a field named `directUrl` with the following: +Then point `prisma.config.ts` to the direct connection string: -```prisma -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -//add-next-line - directUrl = env("DIRECT_DATABASE_URL") -} +```ts file=prisma.config.ts showLineNumbers +import 'dotenv/config' +import { defineConfig, env } from 'prisma/config' + +export default defineConfig({ + schema: 'prisma/schema.prisma', + datasource: { + url: env('DIRECT_DATABASE_URL'), + }, +}) ``` Migrations and introspections will use the `directUrl` connection string rather than the one defined in `url` when this configuration is provided. @@ -134,7 +130,9 @@ Add the following to extend your existing Prisma Client instance with the Accele import { PrismaClient } from '@prisma/client' import { withAccelerate } from '@prisma/extension-accelerate' -const prisma = new PrismaClient().$extends(withAccelerate()) +const prisma = new PrismaClient({ + accelerateUrl: process.env.DATABASE_URL, +}).$extends(withAccelerate()) ``` If you are going to deploy to an edge runtime (like Cloudflare Workers, Vercel Edge Functions, Deno Deploy, or Supabase Edge Functions), use our edge client instead: @@ -143,7 +141,9 @@ If you are going to deploy to an edge runtime (like Cloudflare Workers, Vercel E import { PrismaClient } from '@prisma/client/edge' import { withAccelerate } from '@prisma/extension-accelerate' -const prisma = new PrismaClient().$extends(withAccelerate()) +const prisma = new PrismaClient({ + accelerateUrl: process.env.DATABASE_URL, +}).$extends(withAccelerate()) ``` If VS Code does not recognize the `$extends` method, refer to [this section](/accelerate/faq#vs-code-does-not-recognize-the-extends-method) on how to resolve the issue. @@ -155,7 +155,11 @@ Since [extensions are applied one after another](/orm/prisma-client/client-exten If you are using [Prisma Optimize](/optimize) in your application, make sure you apply it _before_ the Accelerate extension. For example: ```ts -const prisma = new PrismaClient().$extends(withOptimize()).$extends(withAccelerate()) +const prisma = new PrismaClient({ + accelerateUrl: process.env.DATABASE_URL, +}) + .$extends(withOptimize()) + .$extends(withAccelerate()) ``` ### 2.5. Use Accelerate in your database queries