## 34.2. How It Works

When running in the regular mode, Postgres Pro spawns a separate backend for each connection request. With connection pooling enabled, the number of backends that can be used for each database/user combination is limited by the session_pool_size value. Once this limit is reached, `postmaster` stops spawning new backend processes for the corresponding sessions and redirects further connection requests to one of the backends that have already been started. Since each Postgres Pro backend can work with a single database only, built-in connection pooler has to maintain separate connection pools for each unique database/user combination. The number of pools is unlimited: each time a new unique session needs to be served, a new pool is added.

To assign sessions to an appropriate pool, `postmaster` needs to know the target database for the client connection, which requires receiving and parsing a startup packet from the client. To avoid a bottleneck at this stage, `postmaster` delegates the task of reading the startup packet to one of the listener processes. The listener fetches the startup packet and returns the result back to `postmaster`. Based on the received information, `postmaster` chooses the pool for this client and redirects the connection to this pool using the file descriptor transfer mechanism.

### Note

Additionally, you can set the dedicated_databases parameter to specify databases that do not participate in connection pooling. Dedicated databases can use an unlimited number of backends, thus getting priority access to available system resources. By default, `postgres`, `template0`, and `template1` databases are declared dedicated.

To avoid substantial changes in Postgres Pro locking mechanism, only transaction-level pooling policy is supported. In this mode, the backend can be rescheduled to another session only after it has completed the current transaction. However, the built-in pooler provides session semantics for pooled connections, so that all changes in the session context made by a client application, such as session configuration parameters, preparing statements, or creating temporary tables, are saved/restored by Postgres Pro when the backend is rescheduled to another session. By contrast, pgbouncer can provide session semantics only in the session pooling mode, which does not limit the number of launched backends.

Pooled sessions are bound to backends and cannot be migrated between them. Migrating a session would also require serialization and transfer of the complete session context, which is a non-trivial task. By default, pooled backends continue running even if all sessions assigned to them have been already terminated. To change this behavior, you can set restart_pooler_on_reload or idle_pool_worker_timeout configuration parameters.