Skip to content
Home › SQL Comparisons › PgBouncer vs Pgpool-II
Comparison · Proxies & Connection Pooling

PgBouncer vs Pgpool-II

PgBouncer is a small, single-purpose connection pooler for PostgreSQL with session, transaction and statement pooling; Pgpool-II is a broader PostgreSQL middleware that adds read/write splitting, read load balancing, automatic failover and its own watchdog, but pools connections only as a per-process cache. The choice depends on whether your problem is connection count or routing and availability.

Last verified November 2026. Versions checked: PgBouncer 1.26.1, Pgpool-II 4.7.3. Licensing and features change; check the official sources for the latest details.

Quick verdict

Short answer

Choose PgBouncer when the problem is too many connections: its transaction pooling lets many clients share a few server connections, and it has little to configure. Choose Pgpool-II when you want one middleware layer to send writes to the primary, spread reads across streaming replicas and react to a failed primary, and you are ready to manage many more settings. Both are free and open source. They are not mutually exclusive: some teams run PgBouncer for pooling in front of, or alongside, a separate routing and failover layer.

How we know: This comparison is research-based: pooling behaviour, routing, failover features, authentication, licences and release history were checked against the PgBouncer and Pgpool-II documentation, changelogs and licence pages on 7 November 2026. We have not deployed either product, so nothing here is a measured result.

PgBouncer is an open source connection pooler for PostgreSQL under the ISC licence. Clients connect to it as if it were PostgreSQL and it hands out server connections from pools keyed by user and database. It offers three modes: session (the default), transaction and statement pooling. The current release is 1.26.1 (14 October 2026); 1.26.0 (23 September 2026) removed the old online restart option -R, and the changelog now points to rolling restarts with so_reuseport instead.

Pgpool-II, from the PgPool Global Development Group, is PostgreSQL middleware under a short BSD-style licence. Besides connection reuse it parses statements, routes writes to the primary and reads to standbys, checks replication delay, performs automatic failover and online recovery, offers an in-memory query cache, and coordinates several Pgpool-II nodes through a watchdog with a virtual IP. The current release is 4.7.3 (29 September 2026), with the 4.3 to 4.6 branches updated the same day.

A pooler and a proxy are different jobs. PgBouncer is a pooler: it reduces server connections but does not decide where a query should run. Pgpool-II is a SQL-aware proxy that also pools. For a managed AWS option, see Amazon RDS Proxy vs PgBouncer.

Side by side

AspectPgBouncerPgpool-II
Product type Connection pooler only Middleware: pooling, routing, load balancing, failover, query cache
Pooling modes Session (default), transaction and statement Per-child-process connection cache reused by later clients with the same user, database and protocol; no transaction pooling documented
Server connections used Bounded by pool settings such as default_pool_size per user and database Up to num_init_children x max_pool per backend (max_pool default 4)
Read/write splitting No; point clients at separate logical databases for primary and replicas Yes: parses SQL, sends writes to the primary and balances reads in streaming_replication mode
Load balancing Host list per database with load_balance_hosts (round-robin, or stick to one host); no role awareness Weighted read balancing per session or per statement, preference lists by database, application or user, replication delay check
Failover No primary detection; usually paired with Patroni, DNS, a virtual IP or HAProxy Automatic failover and online recovery of PostgreSQL nodes
High availability of the middleware itself Run several instances (so_reuseport on one host, or several hosts behind a balancer) Watchdog with virtual IP; at least three Pgpool-II nodes recommended to avoid split brain
Prepared statements Protocol-level prepared statements in transaction mode since 1.21 (max_prepared_statements, default 200) Sessions keep their backend connections, so session features work as on PostgreSQL
Authentication cert, md5, scram-sha-256, trust, hba, ldap, pam; auth_file or auth_query trust, password, md5, scram-sha-256, cert, PAM and LDAP; GSSAPI not supported
Licence and price ISC licence, free BSD-style licence, free
Main trade-off Simple and efficient at pooling, but routing and HA are someone else's job One layer for routing and HA, but many parameters to get right and weaker connection savings

Key differences

How each one saves connections

PgBouncer separates client connections from server connections. In transaction pooling a server connection is lent to a client only for the length of one transaction and then returned, so a few dozen server connections can serve far more clients. The cost is that session state does not survive between transactions: SET, LISTEN, session advisory locks and SQL-level PREPARE are not safe in this mode, although protocol-level prepared statements, which most drivers use, are supported since 1.21. Version 1.26.0 also began tracking every parameter PostgreSQL reports, including search_path on PostgreSQL 18, so settings do not leak between clients.

Pgpool-II works with a pool of child processes. Each child serves one client at a time and keeps up to max_pool cached backend connections; a later client with the same user, database and protocol version reuses one of them. The documentation warns that total backend connections can reach num_init_children times max_pool. Because a client holds its child for the whole session, this cuts connection setup cost but does not multiplex many concurrent clients onto fewer server connections the way PgBouncer transaction pooling does. The upside is that session features behave as they do on a direct connection.

Routing reads and writes

This is the main reason to choose Pgpool-II. In the recommended streaming_replication clustering mode, PostgreSQL replicates on its own and Pgpool-II inspects each statement: writes and anything inside an explicit write transaction go to the primary, while reads can be balanced across standbys by weight, either per session or per statement (statement_level_load_balance). Preference lists can send a given database, application name or user to particular nodes, write_function_list marks functions that modify data, and delay_threshold sends reads back to the primary when a standby lags.

PgBouncer does not look inside queries. You can define one logical database that points at the primary and another that points at replicas, and the application chooses which to use. A comma-separated host list with load_balance_hosts (added in 1.24.0) spreads new server connections across hosts, but PgBouncer does not know which host is the primary.

; pgbouncer.ini: separate entries for writes and reads
[databases]
app    = host=pg-primary port=5432 dbname=app
app_ro = host=pg-replica1,pg-replica2 port=5432 dbname=app

[pgbouncer]
pool_mode = transaction
default_pool_size = 20

Failover and high availability

Pgpool-II includes automatic failover (it can run a failover command when a backend fails), online recovery to bring a node back, and a watchdog that lets several Pgpool-II nodes share a virtual IP so the middleware is not a single point of failure. The watchdog needs at least three nodes to avoid split brain, which adds hosts and configuration. Teams often combine it with external tooling or let Pgpool-II drive promotion, and it is important that only one component is in charge of failover.

PgBouncer has no failover logic. The common pattern is to let Patroni or a managed service handle promotion and to point PgBouncer at a stable endpoint such as a virtual IP, a DNS name or HAProxy. PgBouncer itself is usually made highly available by running more than one instance. Note that 1.26.0 removed online restart (-R), so upgrades now rely on rolling restarts with so_reuseport or on several instances behind a balancer.

Operational complexity

PgBouncer has a short configuration file, an admin console with SHOW commands, and online reload for most settings. It is single-threaded, using one CPU core per process, so heavy deployments run several processes with so_reuseport. Pgpool-II has many more parameters and five clustering modes, and its documentation is correspondingly long. A wrong setting can send writes to the wrong node or serve stale reads, so treat its configuration as part of your database design and review it with each release branch.

Pricing and licensing

Both are free. PgBouncer is distributed under the ISC licence (COPYRIGHT file in the GitHub repository) and the project sells no paid edition. Pgpool-II is distributed under a BSD-style permission notice published on pgpool.net, and the project sells nothing either. Your costs are the servers or containers you run them on and the staff time to operate them. A Pgpool-II watchdog setup needs at least three nodes; PgBouncer is often run as a sidecar or on the application or database hosts. Some managed PostgreSQL services include PgBouncer in their own pricing; check your provider.

Pricing checked on the vendors' official pages on 7 November 2026. Prices change; confirm before buying.

Where each one leads

PgBouncer strengths

  • Transaction pooling lets many clients share a small number of server connections
  • Small, single-purpose and quick to configure, with packages on most Linux distributions
  • Protocol-level prepared statements work in transaction mode since 1.21
  • Wide choice of authentication methods, including auth_query, LDAP (1.25.0) and PAM
  • Widely used, including inside several managed PostgreSQL services

Pgpool-II strengths

  • SQL-aware read/write splitting and weighted read load balancing
  • Replication delay check that keeps reads on the primary when standbys lag
  • Automatic failover, online recovery and a watchdog for its own high availability
  • In-memory query cache for repeated SELECT statements
  • Session features behave as on a direct connection, because clients keep their backend connection

Limitations

PgBouncer limitations

  • No read/write splitting or primary detection
  • Transaction and statement modes break SET, LISTEN, session advisory locks and SQL PREPARE
  • Single-threaded per process; scaling across cores needs several processes
  • Online restart was removed in 1.26.0, so plan rolling upgrades

Pgpool-II limitations

  • Many parameters and modes; misconfiguration can misroute writes or serve stale reads
  • Connection cache per child process saves fewer server connections than transaction pooling
  • Watchdog high availability needs at least three Pgpool-II nodes
  • GSSAPI authentication is not supported

When to choose each

Choose PgBouncer if

  • You hit max_connections from autoscaled application servers, workers or serverless functions
  • Your application is stateless enough for transaction pooling
  • Failover is already handled by Patroni, a managed service or a virtual IP
  • You want a small component with little to configure and patch

Choose Pgpool-II if

  • You run a primary with streaming replicas and want reads spread without changing the application
  • You want one middleware layer to follow a failed primary
  • You need routing by database, application name or user, or a replication lag threshold
  • You want a query cache for repeated reads

When neither is right

  • You are on AWS and prefer a managed pooler with IAM authentication: see Amazon RDS Proxy vs PgBouncer.
  • A single-threaded pooler has become the bottleneck: compare Odyssey vs PgBouncer.
  • You only need TCP failover to whichever node is primary: a generic balancer such as HAProxy with health checks from your HA manager may be enough.
  • Your application servers already pool connections well and the server is not near its limit: driver-side pooling may be all you need.

Final recommendation

Bottom line

If your PostgreSQL server is running out of connections, PgBouncer is the more direct fix: transaction pooling saves far more connections than a per-process cache, and there is little to configure. If you need the middleware itself to split reads from writes, balance across replicas and react to failover, Pgpool-II is the more complete tool, at the price of a much larger configuration surface. Decide which component owns failover first, then pick the pooler or proxy that fits around it.

Frequently asked questions

Can I use PgBouncer and Pgpool-II together?

Yes, some teams do: PgBouncer handles transaction pooling close to the application and Pgpool-II handles routing and failover in front of the database servers. It adds a hop and two sets of configuration, so only do it when you need both jobs done.

Does Pgpool-II do transaction pooling like PgBouncer?

No transaction-level pooling is documented. Pgpool-II caches backend connections per child process (up to max_pool each) and reuses one when a later client has the same user, database and protocol version. A client keeps its child process for the session.

Does PgBouncer split reads and writes?

No. It does not parse queries or know which host is the primary. You can define separate logical databases for the primary and for replicas and have the application choose, or use a SQL-aware proxy such as Pgpool-II.

Which one is easier to run?

PgBouncer, by a wide margin: it has a short configuration and a single job. Pgpool-II has five clustering modes and many parameters, and a watchdog setup needs at least three nodes.

What changed in PgBouncer 1.26?

Version 1.26.0 (23 September 2026) tracks all parameters PostgreSQL reports by default, including search_path, adds pool_idle_timeout and per-user query_wait_timeout, and removes online restart (-R); the changelog recommends rolling restarts with so_reuseport. 1.26.1 (14 October 2026) fixed three security issues.

Sources

Checked November 2026.

How we research comparisons: our editorial method.

More comparisons

Browse all SQL comparisons or the tools directory.