// 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
[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 = 20The 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
| PgBouncer | Pgpool-II | |
|---|---|---|
| Main purpose | connection pooling | load balancing, failover, pooling |
| SQL parsing | no | yes |
| Read/write split | no | yes |
| Configuration complexity | low | high |
| Typical placement | in front of each database | in 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.
Useful links
// 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 …
VPS setup, server setup
2026-05-12 · ★ 5/5
Excellent work! Set up the server very quickly, installed the control panel, and configured the IP. Definitely recommend!
Excellent work! Very quickly set up the server, installed the panel, configured the IP I can definitely recommend it!
Everything was excellent; helped promptly and professionally. Thank you — I recommend them to the community.
Everything's great, helped promptly and professionally, thank you, I recommend it to the community
VPS setup, server setup
2026-04-16 · ★ 5/5
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly, resolved the technical problems, and helped me understand them — many thanks. I'm satisfied with the result.
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly to the request, helped sort things out and resolved the technical problems and helped clarify …
VPS setup, server setup
2026-02-18 · ★ 5/5
Everything was done quickly and efficiently. I recommend.
Everything was done quickly and efficiently. I recommend.
VPS setup, server setup
2026-01-17 · ★ 5/5
Everything went well; the contractor responded quickly to questions and helped resolve the issue. Thanks!
Everything went well, the contractor responded quickly to questions and helped resolve the issue. Thank you!
VPS setup, server setup
2025-12-16 · ★ 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)
Или оставьте заявку здесь:
// Related