Skip to content

Commit

Permalink
feat: PgBouncer => external connection pooler (#5427)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Ruheni <[email protected]>
  • Loading branch information
janpio and ruheni authored Nov 23, 2023
1 parent 2f671b7 commit 38e4f20
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 17 deletions.
1 change: 1 addition & 0 deletions cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"libgcc",
"libc",
"Distroless",
"Supavisor",
"inshellisense",
],
"patterns": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,4 @@ Error: undefined: Database error
Error querying the database: db error: ERROR: prepared statement "s0" already exists
```

See [Prisma Migrate and PgBouncer workaround](/guides/performance-and-optimization/connection-management/configure-pg-bouncer) for further information and a workaround. Follow [GitHub issue #6485](https://github.com/prisma/prisma/issues/6485) for updates.
See [Prisma Migrate and PgBouncer workaround](/guides/performance-and-optimization/connection-management/configure-pg-bouncer) for further information and a workaround.
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
---
title: Configure Prisma Client with PgBouncer
title: Configure Prisma Client with an external connection pooler (like PgBouncer)
---

<TopBlock>

PgBouncer holds a connection pool to the database and proxies incoming client connections by sitting between Prisma Client and the database. This reduces the number of processes a database has to handle at any given time. PgBouncer passes on a limited number of connections to the database and queues additional connections for delivery when space becomes available.
An external connection pooler like PgBouncer holds a connection pool to the database, and proxies incoming client connections by sitting between Prisma Client and the database. This reduces the number of processes a database has to handle at any given time.

Usually, this works transparently, but some connection poolers only support a limited set of functionality. One common feature that external connection poolers do not support are named prepared statements, which Prisma uses. For these cases, Prisma can be configured to behave differently.

</TopBlock>

## Add <inlinecode>pgbouncer</inlinecode> to the connection URL
## PgBouncer

To use Prisma Client with PgBouncer from a serverless function, add the `?pgbouncer=true` flag to the PostgreSQL connection URL:
### Set PgBouncer to transaction mode

```
postgresql://USER:PASSWORD@HOST:PORT/DATABASE?pgbouncer=true
```
For Prisma Client to work reliably, PgBouncer must run in [**Transaction mode**](https://www.pgbouncer.org/features.html).

Transaction mode offers a connection for every transaction – a requirement for the Prisma Client to work with PgBouncer.

> Note: `PORT` specified for PgBouncer pooling sometimes different from the default `5432` port. Check database provider docs for the exact port number, otherwise adding `?pgbouncer=true` won't work.
### Add <inlinecode>pgbouncer=true</inlinecode> to the connection URL

## Set PgBouncer to transaction mode
To use Prisma Client with PgBouncer, add the `?pgbouncer=true` flag to the PostgreSQL connection URL:

Additionally, for Prisma Client to work reliably, PgBouncer must run in [**Transaction mode**](https://www.pgbouncer.org/features.html).
```
postgresql://USER:PASSWORD@HOST:PORT/DATABASE?pgbouncer=true
```

_Transaction mode_ offers a connection for every transaction – a requirement for the Prisma query engine to work with PgBouncer.
> Note: `PORT` specified for PgBouncer pooling is sometimes different from the default `5432` port. Check your database provider docs for the correct port number.
<details>
<summary>How `pgbouncer` mode works in Prisma</summary>

- Prisma opens a transaction for every query – even when just reading data, allowing Prisma to use prepared statements.
- Prisma does not try to set the `search_path`, which is not supported by PgBouncer.
- Prisma cleans up already present prepared statements in the connection by running `DEALLOCATE ALL` before preparing and executing Prisma Client queries.
- Prisma opens a transaction for every query case – even when just reading data, allowing Prisma to use prepared statements.
- Prisma also disables any prepared statement or type query caches.

</details>

## Prisma Migrate and PgBouncer workaround
### Prisma Migrate and PgBouncer workaround

Prisma Migrate uses **database transactions** to check out the current state of the database and the migrations table. However, the Schema Engine is designed to use a **single connection to the database**, and does not support connection pooling with PgBouncer. If you attempt to run Prisma Migrate commands in any environment that uses PgBouncer for connection pooling, you might see the following error:

Expand All @@ -57,11 +63,19 @@ The block above uses a PgBouncer connection string as the primary URL using `url

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](/data-platform/classic-projects/data-proxy/prisma-cli-with-data-proxy#prisma-cli-commands-that-require-a-direct-database-connection) to the database, such as `prisma migrate dev` or `prisma db push`, are invoked.

## PgBouncer with different database providers
### PgBouncer with different database providers

There are sometimes minor differences in how to connect directly to a Postgres database that depend on the provider hosting the database.

Below are links to information on how to set up these connections with providers who have setup steps not covered here in our documentation:

- [Connecting directly to a PostgreSQL database hosted on Digital Ocean](https://github.com/prisma/prisma/issues/6157)
- [Connecting directly to a PostgreSQL database hosted on ScaleGrid](https://github.com/prisma/prisma/issues/6701#issuecomment-824387959)

## Supabase Supavisor

Supabase's Supavisor behaves similar to [PgBouncer](#pgbouncer). You can add `pgbouncer=true` to your connection pooled connection string.

## Other external connection poolers

Although Prisma does not have explicit support for other connection poolers, if the limitations are similar to the ones of [PgBouncer](#pgbouncer) you can usually also use `pgbouncer=true` in your connection string to put Prisma in a mode that works with them as well.
8 changes: 6 additions & 2 deletions vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -1716,13 +1716,17 @@
"destination": "/docs/data-platform/platform-console/support"
},
{
"source": "/docs/data-platform/accelerate/testing",
"destination": "/docs/data-platform/accelerate/evaluating"
"source": "/docs/guides/performance-and-optimization/connection-management/configure-pg-bouncer",
"destination": "/docs/guides/performance-and-optimization/connection-management/configure-for-external-connection-pooler"
},
{
"source": "/docs/data-platform/classic-projects/platform/billing",
"destination": "https://www.prisma.io/pricing"
},
{
"source": "/docs/data-platform/accelerate/testing",
"destination": "/docs/data-platform/accelerate/evaluating"
},
{
"source": "/docs/data-platform/classic-projects/platform/billing/plans-and-quotas",
"destination": "https://www.prisma.io/pricing"
Expand Down

1 comment on commit 38e4f20

@vercel
Copy link

@vercel vercel bot commented on 38e4f20 Nov 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./

docs-prisma.vercel.app
prisma2-docs.vercel.app
docs-git-main-prisma.vercel.app

Please sign in to comment.