Beyond the Edge: The Comprehensive State of PostgreSQL Connection Poolers

Main Facts
Database connection management remains one of the foundational architectural challenges in modern software engineering. While relational database systems like PostgreSQL are marvels of data integrity and transactional durability, they have historically struggled to scale gracefully under the immense concurrency demands of modern, distributed applications. Every incoming client connection—whether from an ephemeral serverless function, a scaling Kubernetes cluster, or a traditional monolith—spawns a dedicated backend process or thread. This model consumes precious memory, degrades CPU cache efficiency, and eventually leads to hard connection limits.
To bridge this chasm, engineers rely on connection poolers—proxy layers that sit between clients and the database, multiplexing thousands of incoming connections onto a tightly managed, reusable pool of persistent backend connections.
Following a comprehensive look at foundational poolers, a vast landscape of specialized tools remains for systems architects operating on specific cloud infrastructures, scaling past single-core constraints, or managing multi-tenant SaaS platforms. This analysis covers the next tier of download-and-run poolers—Odyssey, pgagroal, Supavisor, PgDoorman, and ProxySQL—alongside managed cloud implementations, edge caching mechanisms, and native application-level pools.
Understanding these options requires navigating a specialized technical vocabulary:
- Session Pooling: Holds a server connection for the entire duration of the client connection, preventing connection reuse until the client explicitly disconnects.
- Transaction Pooling: Returns the server connection back to the pool immediately upon a
COMMIT. The core complexity here revolves around managing ephemeral session state—such asSETstatements, prepared statements, advisory locks,LISTEN/NOTIFYchannels, and temporary tables.
Chronology and Evolution
The ecosystem of PostgreSQL connection pooling has evolved significantly over the past decade, shifting away from simple, single-threaded models toward multi-threaded architectures, distributed clustering, and specialized language bindings.
- November 2016: Yandex begins development on Odyssey, an advanced multi-threaded C-based connection pooler designed to handle massive enterprise workloads natively.
- January 2019: Konstantin Knizhnik of Postgres Professional attempts to introduce a built-in connection pooler patch to the
pgsql-hackersmailing list, though it is ultimately rejected for core PostgreSQL inclusion. (Enterprise forks later deprecate this approach in favor of external utilities like PgBouncer). - August 2019: Jesper Pedersen initiates pgagroal, a process-per-client model utilizing modern shared memory and
io_uringto avoid single-point-of-failure risks. - December 2019: Odyssey reaches its official 1.0 milestone, establishing itself as a robust, enterprise-grade alternative to PgBouncer.
- November 2020: pgagroal releases version 1.0.0, cementing its position in the open-source community.
- January 2023: Supabase commits the initial code for Supavisor, addressing multi-tenant database hosting and serverless scaling limitations.
- September 2024: ProxySQL, long the default proxy for MySQL environments, introduces native PostgreSQL support with version 3.0.0-alpha, bringing advanced query routing and rule engines to the Postgres ecosystem.
- March 2025: Ozon launches the public repository for PgDoorman, a Rust-based, multi-threaded pooler rewritten from a PgCat fork.
- June 2026: Sugu Sougoumarane releases the v0.1 alpha of Multigres, an ambitious adaptation of Vitess for PostgreSQL featuring a unified "multigateway" and "multipooler" architecture.
- Throughout 2026: Minor and major version bumps across all platforms—including Odyssey v1.5.2, pgagroal v2.1.0, Supavisor v2.9.13, and PgDoorman v3.11.0—reflect active hardening, enhanced observability, and tighter integration with orchestrators like Patroni.
Deep Dive: The Open-Source Download-and-Run Poolers
1. Odyssey: PgBouncer, Plural
Developed by Yandex and utilized heavily in their managed PostgreSQL infrastructure, Odyssey (currently at release v1.5.2 as of September 2026) is a multi-threaded pooler written in C. It relies on its own coroutine library, machinarium, to handle thousands of concurrent requests efficiently. Worker threads manage authentication and proxying while sharing a single unified server connection pool.
Odyssey handles session and transaction modes natively, alongside an experimental statement mode. Features like maintain_params ensure that client parameters set via SET are automatically reapplied when a client switches server connections. It also features robust automated recovery: pool_rollback cancels open transactions and pool_cancel halts running queries rather than aggressively terminating broken connections. Advanced features include target_session_attrs for intelligent routing to read-write or read-only hosts, online restarts via SIGUSR2, and a "soft OOM" mode.
2. pgagroal: A Process for Everyone
Started by Jesper Pedersen, pgagroal (v2.1.0, April 2026) rejects the single-threaded thread model, instead utilizing a fork() process-per-client architecture. The project argues that a crash on a single client connection should never compromise the broader pool.
Unlike older process-per-client tools, pgagroal stores its central pool inside a shared memory segment, tracking connection states via atomic operations. Network I/O is accelerated on Linux using io_uring. While it offers performance, session, and auto-switching pipeline modes, its transaction pipeline has strict limitations—session states like SET and temporary tables are not automatically reset between clients. It is best treated as a dedicated session pooler equipped with Prometheus integration, Grafana dashboards, and failover script hooks.
3. Supavisor: A Pooler for Landlords
Built by Supabase for massive multi-tenant SaaS workloads, Supavisor (v2.9.13, September 2026) is written in Elixir and runs on the Erlang VM (BEAM). Designed to support hundreds of thousands of ephemeral serverless connections, Supavisor acts as a distributed cluster. Tenants are identified via usernames (postgres.dev_tenant), TLS SNI, or connection options.

The first node in the cluster to receive a request initializes the tenant’s pool, while peer nodes proxy traffic to it. This design ensures backend connection counts remain strictly bounded (default_pool_size), regardless of how many cluster nodes are added. While it supports transaction and session modes, its primary trade-off is architectural complexity: it requires a dedicated metadata database and a multi-node cluster to replace what would otherwise be a lightweight C binary.
4. PgDoorman: The Rust-Based Contender
Evolving out of a fork of PgCat, Ozon’s PgDoorman (v3.11.0, June 2026) is written in Rust and operates on a multi-threaded model with a shared global pool. It supports transaction and session modes, actively stripping out session pollution by executing RESET ALL, DEALLOCATE ALL, or CLOSE ALL upon connection check-in.
PgDoorman excels at handling unnamed prepared statements commonly generated by modern drivers (such as pgx, Npgsql, and asyncpg), automatically rewriting them to shareable named statements. Furthermore, it integrates tightly with Patroni, querying the Patroni REST API for automatic failover routing, supporting live binary upgrades without dropping client TLS sessions, and providing native Prometheus metrics and a web console.
5. ProxySQL: The MySQL Veteran Learns PostgreSQL
Having dominated the MySQL ecosystem for a decade, ProxySQL (v3.0.11, September 2026) introduced native PostgreSQL support via a multi-threaded C++ architecture. Configuration is entirely dynamic, managed through an in-memory table structure accessed via an administrative psql interface (LOAD to runtime, SAVE to disk).
ProxySQL terms its transaction pooling "multiplexing." It parses basic session configurations like SET commands, while dropping multiplexing entirely when it detects unmovable states such as temporary tables or advisory locks. While its query rule engine, caching, and automatic read/write splitting based on pg_is_in_recovery() make it extraordinarily powerful, its documentation remains heavily MySQL-centric, making it a niche choice for purely PostgreSQL-native environments.
Supporting Data: Managed Cloud and Edge Solutions
Cloud providers and serverless platforms have largely internalized connection pooling, embedding managed solutions directly into their database offerings.
| Service | Architecture / Underlying Tech | Default Port | Key Limitations & Caveats |
|---|---|---|---|
| Azure Database for PostgreSQL | PgBouncer 1.25.2 (pgbouncer.enabled) |
6432 |
Hosted on the database VM; restarts alongside the server; unavailable on Burstable tiers. |
| Google Cloud SQL | Managed Connection Pooling | 6432 |
Restricted to Enterprise Plus editions; enabling forces a database restart. |
| AlloyDB | Managed connection pooling | 6432 |
Inherits standard transaction-mode limitations regarding session state. |
| Neon | Scalable PgBouncer integration | Custom (-pooler suffix) |
Migrations and LISTEN/NOTIFY require bypassing the pooler via the direct hostname. |
| Supabase | Shared Supavisor / Dedicated PgBouncer | 6543 (Transaction) |
Transaction mode lacks native support for named prepared statements. |
Edge and Serverless Pooling
For serverless architectures where traditional persistent sockets are impossible, edge poolers bridge the gap:
- Cloudflare Hyperdrive: Maintains regional pools close to databases, handing off connections to Cloudflare Workers with transaction-mode safety and query result caching.
- Prisma Accelerate: Performs a similar function for the Prisma ORM, routing queries efficiently over HTTP.
Implications for System Architects
A common operational misconception is that external poolers should entirely replace application-level connection pools (such as HikariCP, pgxpool, or SQLAlchemy). In reality, turning off application-level pooling can be catastrophic.
Without an application pool, every single incoming HTTP request or background worker thread forces a fresh TCP handshake, TLS negotiation, and SCRAM authentication exchange directly against the pooler—creating massive CPU bottlenecks on single-threaded proxies like PgBouncer. Conversely, when autoscaling containerized environments (such as Kubernetes pods scaling from 5 to 200 replicas), application-level pools multiply exponentially, exhausting database connections instantly. The optimal architecture uses application pools for local thread coordination, coupled with an external transaction pooler (such as Odyssey, PgDoorman, or PgBouncer) to absorb the broader concurrency multiplier.
Summary Scorecard
| Pooler | Inception | Runtime Model | Supported Modes | SET Handling in Transaction Mode |
Key Differentiators |
|---|---|---|---|---|---|
| Odyssey | 2016 | Multi-threaded (C) | Session, Transaction | Remembered and re-applied | Server role routing, online restarts, broad auth support. |
| pgagroal | 2019 | Process-per-client (C) | Session, Transaction | Leaks state (requires session mode) | Shared memory tracking, io_uring, failover scripts. |
| Supavisor | 2023 | Clustered (Elixir/BEAM) | Session, Transaction, Native | Matches PgBouncer behavior | Native multi-tenancy, massive cluster scaling. |
| PgDoorman | 2025 | Multi-threaded (Rust) | Session, Transaction | Reset at check-in | Patroni integration, unnamed prepared statement rewriting. |
| ProxySQL | 2024 (PG) | Multi-threaded (C++) | Multiplexing (On/Off) | Parsed and tracked | Advanced query rules, caching, traffic mirroring. |
Architectural Recommendations
- For High-Concurrency Monoliths: If a single PgBouncer instance is insufficient, Odyssey provides robust authentication and multi-threaded performance, while PgDoorman excels with Patroni integration and modern driver statement rewriting.
- For Multi-Tenant SaaS: Supavisor offers unmatched horizontal scalability across tenant boundaries.
- For Cloud-Native Deployments: Leverage native managed solutions (Azure, Cloud SQL, Supabase) while auditing failover behavior to avoid unexpected client disconnections.
- For Small, Long-Lived Applications: Rely on built-in driver pools and avoid introducing unnecessary proxy overhead.
