Skip to main content

Top 4 Open Source Postgres Connection Poolers (2026)

Adela · Jul 10, 2026

Update history

  1. Remove cf-pgbouncer (archived by Cloudflare) and Supavisor. Add Odyssey and PgDoorman. Expand PgDog. Refresh all facts.
  2. Initial version.

This post is maintained by Bytebase, an open-source database governance platform. We update the post every year.

Postgres's connection model is the part that bites. Each client connection is a dedicated backend process with real memory and CPU cost, opening connections is expensive, and even idle sessions hold resources. Picking max_connections is guesswork: too low and your app queues, too high and the database burns RAM on connections that mostly sit idle.

A connection pooler sits between your apps and Postgres, reusing a small set of server connections across many clients.

Before and after: 1,000 direct client connections blow past Postgres max_connections, while a connection pooler maps them onto 20 server connectionsBefore and after: 1,000 direct client connections blow past Postgres max_connections, while a connection pooler maps them onto 20 server connections

Here's a tour of the leading open-source options.

PgBouncer

https://github.com/pgbouncer/pgbouncer

What it is. A lightweight, single-binary pooler that's been in production for years. It supports session, transaction, and statement pooling modes, per-user/per-database connection limits, and prepared statements in transaction mode. It's actively maintained — the 1.25.2 release (May 2026) fixed four CVEs in SCRAM and admin-console handling.

Why it's popular:

  • Small footprint, deploys almost anywhere.
  • Works with managed Postgres (RDS, AlloyDB, etc.) and on-prem clusters.
  • Wired into many operators (CloudNativePG ships a Pooler CRD).

The caveat: PgBouncer is single-threaded. A busy instance bottlenecks on one CPU core; the standard remedy is several instances behind a load balancer. (Cloudflare archived its multi-tenant fork in June 2026 — upstream is the way.)

Good fit for: most apps that need stable concurrency control and simple operations.

Odyssey

https://github.com/yandex/odyssey

What it is. A multi-threaded C pooler from Yandex, built because a single-threaded PgBouncer didn't survive Yandex-scale traffic. It does session and transaction pooling plus a richer request-routing layer, and it's proven in very large production setups — Yandex runs it in front of its managed Postgres fleet. v1.5.0 landed in January 2026.

Why it scales:

  • Worker threads share the global connection pools, so one instance spreads across cores — no fleet of single-threaded processes each hoarding its own connections.
  • Transaction pooling cleans up after clients: Odyssey tracks transaction state, and when a client vanishes mid-transaction it cancels the running query and rolls back the abandoned transaction before the connection is reused. Since v1.5.0, prepared statements survive transaction pooling by default (pool_reserve_prepared_statement).
  • Operations at fleet scale: per-connection UUIDs for end-to-end log tracing, built-in Prometheus metrics, and auth that reaches beyond md5/SCRAM to PAM and LDAP, with full TLS on both sides.

The trade-off is complexity. Odyssey brings more knobs, its own configuration language, and documentation that's thinner than PgBouncer's — it assumes you have (or are) a platform team.

Good fit for: high-throughput workloads where PgBouncer saturates a core and you'd rather scale up one pooler than orchestrate a fleet.

PgDoorman

https://github.com/ozontech/pg_doorman

What it is. A multi-threaded Rust pooler from Ozon, one of the largest e-commerce platforms in Russia — in production there for over three years across Go, .NET, Python, and Node.js workloads. It does session and transaction pooling under an MIT license; v3.11.0 shipped in June 2026. digoal, the prolific Chinese Postgres evangelist, put it on the map in July 2026.

Why it stands out — transparent transaction pooling:

  • Prepared statements without driver surgery: anonymous statements are remapped to named ones, so backends reuse plans.
  • One shared pool across all worker threads — no multi-instance fleet with skewed load.
  • Admin console, graceful binary upgrades, Prometheus exporter, Patroni-assisted failover.

The caveat: it's deliberately narrow — no load balancing, sharding, or routing — and the transparency covers the protocol, not session semantics: SET and LISTEN/NOTIFY still break. (Its self-reported benchmarks run 3–4× ahead of PgBouncer, disclaimed by the project itself: "Benchmarks always lie to you.")

Good fit for: teams whose blocker is transaction pooling's compatibility tax, and who want pooling only — nothing else.

PgDog

https://github.com/pgdogdev/pgdog

What it is. A multi-threaded Rust proxy that rolls connection pooling, load balancing, and sharding into one layer, backed by Y Combinator and $5.5M in funding. It succeeds PgCat, the Instacart-born pooler by the same author, and supports online resharding via logical replication. Releases ship weekly, and the project reports 2M+ queries per second across dozens of production deployments.

Why it's differenta real SQL parser keeps the Postgres features other poolers make you give up:

  • SET and Row-Level Security keep working: per-client session state is re-applied before each query.
  • LISTEN / NOTIFY survive transaction pooling via in-process broadcast channels.
  • Transparent prepared statements, one Tokio process across all cores, and a PgBouncer-style admin database plus OpenMetrics.

The caveat: the more the proxy does, the more of your traffic architecture lives inside it — and its AGPL-3.0 license is the most restrictive here.

Good fit for: teams that want one proxy for pooling, routing, and scale-out, and want a company on the other end of the pager. PgDog is the only option here with a commercial vendor behind it.


Feature comparison

Project

PgBouncerOdysseyPgDoormanPgDog
LanguageCCRustRust
LicenseISCBSD-3-ClauseMITAGPL-3.0
GitHub stars4.2k3.5k0.3k5.1k
Commercial vendor

Pooling — the last two rows are what transaction pooling usually breaks.

PgBouncerOdysseyPgDoormanPgDog
ModesSession, transaction, statementSession, transactionSession, transactionSession, transaction
Multi-core❌ single-threaded✅ multi-threaded✅ multi-threaded, shared pool✅ multi-threaded
Prepared statements✅ opt-in (max_prepared_statements)✅ transparent, with plan cache
Session state (SET, LISTEN/NOTIFY)

Beyond pooling

PgBouncerOdysseyPgDoormanPgDog
Built-in Prometheus metrics❌ external exporter✅ OpenMetrics
Load balancing / routing✅ request routing❌ by design
Sharding❌ by design✅ online resharding

A ❌ in the last table isn't always a gap. PgDoorman deliberately stops at pooling — Ozon's position is that routing belongs in a different layer. The more rows a proxy fills in, the more of your traffic architecture lives inside it.


Our pick

Loading diagram…

One pooler per quadrant — the four don't compete head-on. Pick your row (pool only, or also route and shard?), then your column (production mileage, or a modern engine?). Two choices cover most teams:

Free: PgBouncer. The default for a reason: small, proven, and wired into every managed Postgres and operator you're likely to touch. Its one real limit is the single thread, and the fix is well-trodden — a few instances behind a load balancer.

Commercial: PgDog. The only pooler here with a company behind it, and it earns the spot on merit: pooling, load balancing, and sharding in one multi-threaded proxy that keeps SET, Row-Level Security, and LISTEN/NOTIFY working under transaction pooling.

Narrow constraints: Odyssey when one PgBouncer core saturates, PgDoorman when transaction pooling keeps fighting your drivers. Both are open-source only — no vendor to call.

Whichever you pick, watch for:

  • Pooling mode. Session maximizes compatibility, transaction wins concurrency but breaks session state, statement is rarely what you want.
  • Limits at the pooler. Per-user and per-database caps protect Postgres from thundering herds.
  • Prepared statements. All four now handle them at the protocol level — opt-in on PgBouncer (max_prepared_statements) — but test your own ORM rather than assuming.
  • HA, like any stateless proxy. Multiple poolers behind a VIP or load balancer, with health checks and drain/reload flows.
  • The basics. Right-size the pool, the client cap, and timeouts against actual concurrency — pools are per user/db/host tuple.

Treat the pooler as part of your capacity and SLO strategy: cap concurrency, keep transactions short, and watch pool saturation.

Back to blog

Explore the standard for database governance