|
| 1 | +--- |
| 2 | +title: 'Open Source Postgres Connection Pooler' |
| 3 | +author: Adela |
| 4 | +updated_at: 2025/10/03 18:00:00 |
| 5 | +feature_image: /content/blog/open-source-postgres-connection-pooler/cover.webp |
| 6 | +tags: Industry |
| 7 | +description: List of open source postgres connection poolers |
| 8 | +--- |
| 9 | + |
| 10 | +Postgres is famously robust, but its connection model isn't. Each client connection maps to a dedicated backend process with non-trivial memory and CPU overhead. Spinning up and tearing down connections is expensive, and even "idle" sessions consume resources. Choosing a safe `max_connections` is more art than science: too low and your app queues; too high and the database wastes RAM and scheduler time. |
| 11 | + |
| 12 | +A connection pooler sits between apps and Postgres to reuse a small number of server connections across many clients, smoothing spikes and protecting the database. |
| 13 | + |
| 14 | +Below is a quick, practical tour of the leading **open-source** options. |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## PgBouncer (the standard) |
| 19 | + |
| 20 | +https://github.com/pgbouncer/pgbouncer |
| 21 | + |
| 22 | +**What it is.** A lightweight, single-binary connection pooler that's been battle-tested for years. It supports **session**, **transaction**, and **statement** pooling modes, each with trade-offs. Recent releases added quality-of-life improvements like **per-user/per-database connection tracking/limits** and better TLS reload behavior; prepared-statement support is now on by default. |
| 23 | + |
| 24 | +**Why it's popular:** |
| 25 | + |
| 26 | +- Minimal footprint and easy to deploy nearly anywhere. |
| 27 | +- Works with managed Postgres (RDS, AlloyDB, etc.) and on-prem clusters. |
| 28 | +- Integrated by many operators (e.g., CloudNativePG offers a `Pooler` CRD). |
| 29 | + |
| 30 | +**Good fit for:** most apps needing stable concurrency control and simple ops. |
| 31 | + |
| 32 | +## Cloudflare's fork of PgBouncer (cf-pgbouncer) |
| 33 | + |
| 34 | +https://github.com/cloudflare/cf-pgbouncer |
| 35 | + |
| 36 | +**What it is.** Cloudflare open-sourced their internal fork to harden multi-tenant ops. It includes **auth bug fixes** and features to enforce **per-user and per-pool isolation**, addressing cases where upstream behavior with HBA auth limited those controls. The fork targets large-scale, multi-tenant environments where noisy-neighbor isolation matters. |
| 37 | + |
| 38 | +**Good fit for:** high-scale providers and anyone needing stricter tenant isolation/concurrency enforcement at the pooler layer. For deeper context on CF's multi-tenant performance isolation goals, see their companion post. |
| 39 | + |
| 40 | +## Supavisor (Supabase) |
| 41 | + |
| 42 | +https://github.com/supabase/supavisor |
| 43 | + |
| 44 | +**What it is.** A **cloud-native** pooler built by Supabase (written in Elixir) that emphasizes horizontal scalability and multi-project tenancy. Supabase demonstrated **handling ~1 million concurrent client connections** in testing, highlighting an architecture designed for massive fan-out with lightweight client slots mapped onto a smaller set of server connections. Supavisor now ships as their default pooler. |
| 45 | + |
| 46 | +**Good fit for:** SaaS platforms or services expecting very high connection counts (IoT, event streams, lots of short-lived clients) and wanting modern autoscaling patterns. |
| 47 | + |
| 48 | +## PgDog |
| 49 | + |
| 50 | +https://github.com/pgdogdev/pgdog |
| 51 | + |
| 52 | +**What it is.** A newer **Rust** project that combines **connection pooling**, **load balancing**, and **sharding** in one layer. It supports **session** and **transaction** pooling "like PgBouncer", and advertises the ability to fan out to **hundreds of thousands of clients** while also offering horizontal scale primitives. Docs include admin views (e.g., `SHOW POOLS`) and telemetry. |
| 53 | + |
| 54 | +**Good fit for:** teams wanting a single, high-performance proxy that also tackles routing and (eventually) scale-out patterns beyond pooling. |
| 55 | + |
| 56 | +--- |
| 57 | + |
| 58 | +## How to choose (and what to watch for) |
| 59 | + |
| 60 | +**1) Pick the pooling mode wisely** |
| 61 | + |
| 62 | +- **Session pooling:** 1 client ↔ 1 server connection for the session's life. Maximum compatibility (works with temp tables, GUCs, prepared statements) but fewer concurrency gains. |
| 63 | +- **Transaction pooling:** server connections are returned to the pool after each transaction - **huge concurrency** boost, but features that rely on session state can break (many ORMs are fine if you avoid session-scoped behaviors). |
| 64 | +- **Statement pooling:** most aggressive; rarely needed outside special cases. |
| 65 | + |
| 66 | +**2) Enforce limits at the pooler** |
| 67 | +Use per-user/per-database caps to protect Postgres from thundering herds and to keep tenants in bounds. Upstream PgBouncer and Cloudflare's fork provide controls here. |
| 68 | + |
| 69 | +**3) Mind prepared statements & features** |
| 70 | +Prepared statements historically clashed with transaction pooling; newer PgBouncer releases improved behavior and defaults, but test your ORM/framework. |
| 71 | + |
| 72 | +**4) Deploy for HA like any stateless proxy** |
| 73 | +Run multiple poolers behind a VIP/Load Balancer; configure health checks and drain/reload flows (especially with TLS). Cloud providers and operators (e.g., CloudNativePG) can simplify this. |
| 74 | + |
| 75 | +**5) Tune the basics** |
| 76 | +Right-size `server_pool_size`, `max_client_conn`, and timeouts based on your workload's **concurrency** and **transaction duration**. Heroku's PgBouncer guidance gives a clear mental model (pools are per user/db/host tuple). |
| 77 | + |
| 78 | +## Quick comparison |
| 79 | + |
| 80 | +| Project | Headline strengths | Maturity | Implementation language | Notes | |
| 81 | +| ---------------- | -------------------------------------------- | ---------------- | -------------- | ---------------------------------------------------------- | |
| 82 | +| **PgBouncer** | Lightweight, ubiquitous, three pooling modes | Very mature | **C** | Great default choice; wide community/packager support. | |
| 83 | +| **cf-pgbouncer** | Multi-tenant isolation; auth fixes | Mature fork | **C** | Useful when you need stricter per-user/pool controls. | |
| 84 | +| **Supavisor** | Cloud-native scale; demonstrated ~1M clients | Young → maturing | **Elixir** | Optimized for massive fan-out and provider use cases. | |
| 85 | +| **PgDog** | Pooler + load balancer + sharder (Rust) | Emerging | **Rust** | Ambitious all-in-one proxy with horizontal scale features. | |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +## Bottom line |
| 90 | + |
| 91 | +- **Start with PgBouncer** for most apps; it's simple, well-documented, and production-proven. |
| 92 | +- If you're a **multi-tenant platform** and need hard per-user/pool isolation, evaluate **Cloudflare's fork**. |
| 93 | +- If your challenge is **sheer connection volume** (hundreds of thousands to millions), **Supavisor** is built for that world. |
| 94 | +- If you also want **routing/sharding** alongside pooling, keep an eye on **PgDog**. |
| 95 | + |
| 96 | +Whichever you choose, treat the pooler as part of your **capacity and SLO strategy**: cap concurrency, keep transactions short, and monitor pool saturation to keep Postgres fast and happy. |
0 commit comments