// Engineering Log

PgBouncer, Pgpool-II and others: A proxy for PostgreSQL 🐘

Published on 2026-09-22

// Fast route

This article belongs to the topic Servers and infrastructure.

Connection pooler for PostgreSQL — a program between the application and the database that keeps a small number of real connections to the server and hands them out to clients in turn. The best known are PgBouncer and Pgpool-II; among newer ones — Odyssey and PgCat.

Why a PostgreSQL pooler

Each connection to PostgreSQL is handled by a separate server process. When an application opens hundreds of connections — many workers, serverless functions, multiple services — the server spends memory and time on processes rather than on queries. A pooler accepts thousands of client connections and multiplexes them over a few dozen server connections. Basic PostgreSQL settings and the place of a pooler in the big picture are described in the third part of the series; here — details.

PgBouncer

PgBouncer is a lightweight single-threaded pooler, the standard choice for most projects. The current branch is 1.25 (release 1.25.2 was published in May 2026). It knows nothing about database structure and only manages connections.

Pool modes

  • session (default) — the server connection is bound to the client until it disconnects. Compatible with everything, but yields almost no savings.
  • transaction — the connection is returned to the pool after the end of a transaction. The main mode for saving connections: hundreds of clients served by a dozen connections.
  • statement — the connection is returned after each statement; multi-statement transactions are forbidden.

What breaks in transaction mode

Between transactions the client may land on a different server connection, so anything that stores session state doesn’t work. According to the PgBouncer documentation the following are incompatible with transaction mode:

  • SET and RESET at session level;
  • LISTEN;
  • cursors WITH HOLD;
  • SQL commands PREPARE and DEALLOCATE;
  • temporary tables with PRESERVE or DELETE ROWS;
  • LOAD;
  • session-level advisory locks.

Prepared statements at the protocol level — used by drivers like JDBC and asyncpg — are supported by PgBouncer in recent versions even in transaction mode: PgBouncer prepares them on the server connections itself. This is controlled by the parameter max_prepared_statements (in current documentation the default is 200; a value of 0 disables support).

Minimal configuration

ini
[databases]
app = host=127.0.0.1 port=5432 dbname=app

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20

The application connects to port 6432 instead of 5432. default_pool_size — how many server connections are kept per “user — database” pair (default 20), max_client_conn — how many clients can connect to PgBouncer itself (default 100).

Pgpool-II

Pgpool-II is not only a pooler but a link for a cluster: read balancing between replicas, automatic failover of the primary server, a watchdog process for Pgpool’s own high availability. The current branch is 4.7 (release 4.7.2, June 2026), branches from 4.3 to 4.7 are supported.

The price for capabilities is complexity: Pgpool-II parses SQL to decide where to send a query, it has more settings and more places to make mistakes. Its pool works in a process-per-client model, so to save connections it is simpler and more effective when used together with PgBouncer that holds the pool.

PgBouncer or Pgpool-II

PgBouncerPgpool-II
Main purposeconnection poolingload balancing, failover, pooling
SQL parsingnoyes
Read/write splitnoyes
Configuration complexitylowhigh
Typical placementin front of each databasein front of a cluster with replicas

If you only need pooling — PgBouncer. If you need automatic distribution of reads to replicas and automatic failover and are willing to maintain a complex configuration — Pgpool-II. For a highly available cluster today people often use Patroni, with PgBouncer and HAProxy in front (more about HAProxy in the proxy series).

Odyssey

Odyssey is a multithreaded pooler created at Yandex, BSD-3-Clause licensed, and actively developed (release 1.5.2 — September 2026). It’s designed for heavy loads where single-threaded PgBouncer is limited by a single CPU core. For most projects it’s overkill, but with tens of thousands of connections it’s worth comparing it to several PgBouncer instances.

PgCat

PgCat is a Rust-based pooler with sharding and load balancing, MIT licensed. The project has noticeably slowed: the last release 0.2.5 was published in November 2024, the last repository changes were in February 2025. Choose it for new production deployments with caution.

Common mistakes

  • Using transaction mode without checking the application. SET search_path, LISTEN or session locks start behaving unpredictably.
  • The pooler as a single point of failure. Run it close to each application server or in two instances.
  • The sum of pools exceeds the server’s max_connections. Count default_pool_size × number of user–database pairs plus a reserve for the administrator.
  • Two pools in a row. A large pool in the application on top of PgBouncer doesn’t save connections and only complicates diagnosis.

// Similar task

If you are dealing with something similar

This article belongs to one of the main working topics. You can keep reading on the topic, go to the homepage to understand what I do, or open the service pages directly.

Article topic

Servers and infrastructure

VPS, Linux, web stack, migrations, hosting, databases, and core operations.

Typical tasks behind this topic

  • Move a site or service to a new server
  • Set up Linux, Nginx, databases, and backups
  • Figure out why the system behaves unstably

// Next step

If you need help with this topic, not just another article, it is better to go straight to the service page. The homepage and topic collection stay available as secondary routes.

Open services

// Reviews

Related reviews

I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler, more affordable solution. In the end I saved time and money. Mikhail — a true expert who works for the client's result, not for the fee. I recommend him!

I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler and more cost-effective solution. In the end I saved budget and time. Mikhail — a true expert who …

kfhzasorin

VPS setup, server setup

2026-05-12 · ★ 5/5

// Contact

Need help?

Get in touch with me and I'll help solve the problem

I reply within one business day (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirm that you are not a bot.

Write and get a quick reply