:::info Quick summary
This page explains how Prisma ORM manages database connections using a connection pool, and how you can configure limits and timeouts for optimal performance.
:::


The query engine manages a **connection pool** of database connections. The pool is created when Prisma Client opens the _first_ connection to the database, which can happen in one of two ways:

- By [explicitly calling `$connect()`](/orm/prisma-client/setup-and-configuration/databases-connections/connection-management#connect) _or_
- By running the first query, which calls `$connect()` under the hood

Relational database connectors use Prisma ORM's own connection pool, and the MongoDB connectors uses the [MongoDB driver connection pool](https://github.com/mongodb/specifications/blob/master/source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst).

<details>
<summary>Questions answered in this page</summary>

- How do I size Prisma's connection pool?
- How do I set pool timeouts and limits?
- When should I use PgBouncer with Prisma?

</details>


## Relational databases

Starting with Prisma ORM v7, relational datasources instantiate Prisma Client with [driver adapters](/orm/overview/databases/database-drivers) by default. Driver adapters rely on the Node.js driver you supply, so connection pooling defaults (and configuration) now come from the driver itself. 

Use the tables below to translate Prisma ORM v6 connection URL parameters to the Prisma ORM v7 driver adapter fields alongside their defaults.


### Prisma ORM v7 driver adapter defaults

The following tables document the default connection pool settings for each driver adapter.

:::tip[Prisma timeouts]

Prisma ORM also has its own configurable timeouts that are separate from the database driver timeouts. If you see a timeout error and are unsure whether it comes from the driver or from Prisma Client, see the [Prisma Client timeouts and transaction options documentation](/orm/prisma-client/queries/transactions#transaction-options).

:::

#### PostgreSQL (using the `pg` driver adapter)

Here are the default connection pool settings for the `pg` driver adapter:

| Behavior | v6 URL parameter | v6 default |  v7 `pg` config field | v7 default |
| --- | --- | --- | --- | --- |
| Pool size | `connection_limit` | `num_cpus::get_physical() * 2 + 1` | `max` | `10` |
| Acquire timeout | `pool_timeout` | `10s` | `connectionTimeoutMillis` | `0` (no timeout) |
| Connection timeout | `connect_timeout` | `5s` | `connectionTimeoutMillis` | `0` (no timeout) |
| Idle timeout | `max_idle_connection_lifetime` | `300s` | `idleTimeoutMillis` | `10s` |
| Connection lifetime | `max_connection_lifetime` | `0` (no timeout) | `maxLifetimeSeconds` | `0` (no timeout) |

<details>
<summary>Example: Matching Prisma ORM v6 defaults with the `pg` driver adapter</summary>

If you want to preserve the same timeout behavior you had in Prisma ORM v6, pass the following configuration when instantiating the driver adapter:

```ts
import { PrismaPg } from '@prisma/adapter-pg'

const adapter = new PrismaPg({
  connectionString: process.env.DATABASE_URL,
  // Match Prisma ORM v6 defaults:
  connectionTimeoutMillis: 5_000, // v6 connect_timeout was 5s
  idleTimeoutMillis: 300_000,     // v6 max_idle_connection_lifetime was 300s
})
```

</details>

:::tip
See the [node-postgres pool documentation](https://node-postgres.com/apis/pool) for details on every available option.
:::

#### MySQL or MariaDB (using the `mariadb` driver)

Here are the default connection pool settings for the `mariadb` driver adapter:

| Behavior | v6 URL parameter | v6 default | v7 `mariadb` config field | v7 default |
| --- | --- | --- | --- | --- |
| Pool size | `connection_limit` | `num_cpus::get_physical() * 2 + 1` | `connectionLimit` | `10` |
| Acquire timeout | `pool_timeout` | `10s` | `acquireTimeout` | `10s` |
| Connection timeout | `connect_timeout` | `5s` | `connectTimeout` | `1s` |
| Idle timeout | `max_idle_connection_lifetime` | `300s` | `idleTimeout` | `1800s` |

<details>
<summary>Example: Matching Prisma ORM v6 defaults with the `mariadb` driver adapter</summary>

If you want to preserve the same timeout behavior you had in Prisma ORM v6, pass the following configuration when instantiating the driver adapter:

```ts
import { PrismaMariaDb } from '@prisma/adapter-mariadb'

const adapter = new PrismaMariaDb({
  host: 'localhost',
  port: 3306,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  // Match Prisma ORM v6 defaults:
  connectTimeout: 5_000, // v6 connect_timeout was 5s
  idleTimeout: 300,      // v6 max_idle_connection_lifetime was 300s (note: in seconds, not ms)
})
```

</details>

:::tip
Refer to the [MariaDB Connector/Node.js pool options](https://mariadb.com/docs/connectors/mariadb-connector-nodejs/connector-nodejs-promise-api#pool-options) for configuration and tuning guidance.
:::

#### SQL Server (using the `mssql` driver)

Here are the default connection pool settings for the `mssql` driver adapter:

| Behavior | v6 URL parameter | v6 default | v7 `mssql` config field | v7 default |
| --- | --- | --- | --- | --- |
| Pool size | `connection_limit` | `num_cpus::get_physical() * 2 + 1` | `pool.max` | `10` |
| Connection timeout | `connect_timeout` | `5s` | `connectionTimeout` | `15s` |
| Idle timeout | `max_idle_connection_lifetime` | `300s` | `pool.idleTimeoutMillis` | `30s` |

<details>
<summary>Example: Matching Prisma ORM v6 defaults with the `mssql` driver adapter</summary>

If you want to preserve the same timeout behavior you had in Prisma ORM v6, pass the following configuration when instantiating the driver adapter:

```ts
import { PrismaMssql } from '@prisma/adapter-mssql'

const adapter = new PrismaMssql({
  server: 'localhost',
  port: 1433,
  database: 'mydb',
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  // Match Prisma ORM v6 defaults:
  connectionTimeout: 5_000, // v6 connect_timeout was 5s
  pool: {
    idleTimeoutMillis: 300_000, // v6 max_idle_connection_lifetime was 300s
  },
})
```

</details>

:::tip
See the [`node-mssql` pool docs](https://tediousjs.github.io/node-mssql/#general-same-for-all-drivers) for details on these fields.
:::

## MongoDB

The MongoDB connector does not use the Prisma ORM connection pool. The connection pool is managed internally by the MongoDB driver and [configured via connection string parameters](https://www.mongodb.com/docs/manual/reference/connection-string-options/#connection-pool-options).

## External connection poolers

You cannot increase the `connection_limit` beyond what the underlying database can support. This is a particular challenge in serverless environments, where each function manages an instance of `PrismaClient` - and its own connection pool.

Consider introducing [an external connection pooler like PgBouncer](/orm/prisma-client/setup-and-configuration/databases-connections#pgbouncer) to prevent your application or functions from exhausting the database connection limit.

## Manual database connection handling

When using Prisma ORM, the database connections are handled on an [engine](https://github.com/prisma/prisma-engines)-level. This means they're not exposed to the developer and it's not possible to manually access them.

## Prisma ORM v6 and before

### How the connection pool works

The following steps describe how the query engine uses the connection pool:

1. The query engine instantiates a connection pool with a [configurable pool size](#setting-the-connection-pool-size) and [pool timeout](#setting-the-connection-pool-timeout).
1. The query engine creates one connection and adds it to the connection pool.
1. When a query comes in, the query engine reserves a connection from the pool to process query.
1. If there are no idle connections available in the connection pool, the query engine opens additional database connections and adds them to the connection pool until the number of database connections reaches the limit defined by `connection_limit`.
1. If the query engine cannot reserve a connection from the pool, queries are added to a FIFO (First In First Out) queue in memory. FIFO means that queries are processed in the order they enter the queue.
1. If the query engine cannot process a query in the queue for **before the [time limit](#default-pool-timeout)**, it throws an exception with error code `P2024` for that query and moves on to the next one in the queue.

If you consistently experience pool timeout errors, you need to [optimize the connection pool](/orm/prisma-client/setup-and-configuration/databases-connections#optimizing-the-connection-pool) .

### Connection pool size

#### Default connection pool size

The default number of connections (pool size) is calculated with the following formula:

```bash
num_physical_cpus * 2 + 1
```

`num_physical_cpus` represents the number of physical CPUs on the machine your application is running on. If your machine has **four** physical CPUs, your connection pool will contain **nine** connections (`4 * 2 + 1 = 9`).

Although the formula represents a good starting point, the [recommended connection limit](/orm/prisma-client/setup-and-configuration/databases-connections#recommended-connection-pool-size) also depends on your deployment paradigm - particularly if you are using serverless.

#### Setting the connection pool size

You can specify the number of connections by explicitly setting the `connection_limit` parameter in your database connection URL. For example, with the following `datasource` configuration in your [Prisma schema](/orm/prisma-schema) the connection pool will have exactly five connections:

```prisma
datasource db {
  provider = "postgresql"
  url      = "postgresql://johndoe:mypassword@localhost:5432/mydb?connection_limit=5"
}
```

#### Viewing the connection pool size

The number of connections Prisma Client uses can be viewed using [logging](/orm/prisma-client/observability-and-logging/logging) and built-in APIs provided by the driver adapter being used.

Using the `info` [logging level](/orm/reference/prisma-client-reference#log-levels), you can log the number of connections in a connection pool that are opened when Prisma Client is instantiated.

For example, consider the following Prisma Client instance and invocation:

<CodeWithResult expanded="{true}">
<cmd>

```ts
import { PrismaClient } from '../prisma/generated/client'

const prisma = new PrismaClient({
  log: ['info'],
})

async function main() {
  await prisma.user.findMany()
}

main()
```

</cmd>
<cmdResult>

```text no-copy
prisma:info Starting a postgresql pool with 21 connections.
```

</cmdResult>
</CodeWithResult>

When the `PrismaClient` class was instantiated, the logging notified `stdout` that a connection pool with 21 connections was started.

:::warning

Note that the output generated by `log: ['info']` can change in any release without notice. Be aware of this in case you are relying on the output in your application or a tool that you're building.

:::

If you need even more insights into the size of your connection pool and the amount of in-use and idle connection, you can use the [metrics](/orm/prisma-client/observability-and-logging/metrics) feature (which is currently in Preview).

Consider the following example:

<CodeWithResult expanded="{true}">
<cmd>

```ts
import { PrismaClient } from '../prisma/generated/client'

const prisma = new PrismaClient()

async function main() {
  await Promise.all([prisma.user.findMany(), prisma.post.findMany()])

  const metrics = await prisma.$metrics.json()
  console.dir(metrics, { depth: Infinity })
}

main()
```

</cmd>
<cmdResult>

```json no-copy
{
  "counters": [
    // ...
    {
      "key": "prisma_pool_connections_open",
      "labels": {},
      "value": 2,
      "description": "Number of currently open Pool Connections"
    }
  ],
  "gauges": [
    // ...
    {
      "key": "prisma_pool_connections_busy",
      "labels": {},
      "value": 0,
      "description": "Number of currently busy Pool Connections (executing a datasource query)"
    },
    {
      "key": "prisma_pool_connections_idle",
      "labels": {},
      "value": 21,
      "description": "Number of currently unused Pool Connections (waiting for the next datasource query to run)"
    },
    {
      "key": "prisma_pool_connections_opened_total",
      "labels": {},
      "value": 2,
      "description": "Total number of Pool Connections opened"
    }
  ],
  "histograms": [
    /** ... **/
  ]
}
```

</cmdResult>
</CodeWithResult>

:::info

For more details on what is available in the metrics output, see the [About metrics](/orm/prisma-client/observability-and-logging/metrics#about-metrics) section.

:::

### Connection pool timeout

#### Default pool timeout

The default connection pool timeout is 10 seconds. If the Query Engine does not get a connection from the database connection pool within that time, it throws an exception and moves on to the next query in the queue.

#### Setting the connection pool timeout

You can specify the pool timeout by explicitly setting the `pool_timeout` parameter in your database connection URL. In the following example, the pool times out after `2` seconds:

```prisma
datasource db {
  provider = "postgresql"
  url      = "postgresql://johndoe:mypassword@localhost:5432/mydb?connection_limit=5&pool_timeout=2"
}
```

#### Disabling the connection pool timeout

You disable the connection pool timeout by setting the `pool_timeout` parameter to `0`:

```prisma
datasource db {
  provider = "postgresql"
  url      = "postgresql://johndoe:mypassword@localhost:5432/mydb?connection_limit=5&pool_timeout=0"
}
```

You can choose to [disable the connection pool timeout if queries **must** remain in the queue](/orm/prisma-client/setup-and-configuration/databases-connections#disabling-the-pool-timeout) - for example, if you are importing a large number of records in parallel and are confident that the queue will not use up all available RAM before the job is complete.


---

# Configure Prisma Client with PgBouncer