PgBouncer: A C Connection Pooler for PostgreSQL, and How to Set It Up
lightweight connection pooler for PostgreSQL
At a glance
- What is it?
- PgBouncer sits between your application and PostgreSQL and reuses a small set of backend connections. Here is how it installs, how the pooling modes differ, and where it stops being the right tool.
- Who is it for?
- Adopt PgBouncer if you run many short-lived clients against one PostgreSQL server and want to cap backend connections without changing application code. Do not adopt it if you need query routing, read/write splitting or cross-node load balancing, because it is a pooler rather than a load balancer.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What PgBouncer Solves, and Who Ends Up Running It
PostgreSQL forks a backend process per client connection. That is fine for a handful of long-lived clients and expensive for hundreds of short-lived ones, which is the shape most web and serverless workloads have. PgBouncer is a separate process that accepts client connections and multiplexes them onto a much smaller set of server connections. The repository describes it in one line: a lightweight connection pooler for PostgreSQL.
The audience is fairly narrow. It is for teams whose connection count, not query count, is the bottleneck, and who can accept a proxy hop in front of the database. It is not a query cache and it does not rewrite SQL. If your problem is slow queries, this project will not help, and adding it will only add a component to operate.
How the Pooler Sits Between Client and Server
The architecture is a single C process with its own event loop. The Makefile lists the source files, and they map closely to the job: client.c and server.c handle the two sides, pooler.c manages the pool itself, loader.c reads configuration, janitor.c cleans up, admin.c serves the admin console, and dnslookup.c handles name resolution. Shared protocol and crypto helpers live under src/common.
A detail worth pausing on is DNS. PgBouncer resolves host names at connect time rather than once at configuration load, which is why it needs an asynchronous resolver. The README documents the probing order: c-ares first (parallel, EDNS0, /etc/hosts, SOA lookup), then Libevent's evdns, then glibc's getaddrinfo_a, then plain getaddrinfo. c-ares is described as the most fully-featured implementation and recommended for most uses and binary packaging. The libc fallback is not parallel, and the README notes the legacy backends do not receive much testing anymore. If your deployment depends on re-resolving a database hostname that changes, which is common with managed failover endpoints, this choice matters more than the pooling mode does.
Installing PgBouncer from Source and Registering It as a Windows Service
There is no package manager command in the repository; the README covers building from source with Autoconf or, experimentally, Meson. Autoconf is described as the recommended choice for production builds and packaging for now, while the Meson build is expected to become the default and Autoconf removed in a future release. Dependencies are Libevent 2.0+, pkg-config, a C11 compiler, and OpenSSL 1.0.1+ if you want TLS. c-ares, LDAP and PAM are optional.
A plain Autoconf build looks like this. The prefix decides where the binary and man pages land.
./configure --prefix=/usr/local
make
make installIf you are building from a Git checkout rather than a release tarball, the generated header and configuration files do not exist yet, so autogen.sh has to run first. The README also lists the extra packages this path needs: autoconf, automake, libtool and pandoc.
git clone https://github.com/pgbouncer/pgbouncer.git
cd pgbouncer
./autogen.sh
./configure
make
make installThe Meson route builds straight from a checkout and takes its feature switches as -D options. PAM, LDAP and systemd default to auto under Meson, so each is built when its libraries are present; the README says the Autoconf build does not auto-detect them and needs --with-pam, --with-ldap or --with-systemd instead.
meson setup build --prefix=/usr/local
meson compile -C build
meson install -C buildOn Windows the only supported build environment is MinGW, and the README is explicit that Cygwin and Visual Studio are not supported. The LDAP option is not available there. Running is mostly the same as on Unix, with two exceptions: the -d (daemonize) and -u (switch user) switches do not work. To run it as a service you set service_name in the configuration file and then register the binary.
pgbouncer -regservice config.iniUninstalling uses pgbouncer -unregservice config.ini. If you want output in the Windows event log, set syslog = 1 and register pgbevent.dll with regsvr32 pgbevent.dll first.
Where PgBouncer Is the Wrong Tool
The clearest limitation is categorical: PgBouncer is a connection pooler, not a load balancer. It does not distribute queries across replicas, it does not parse and route SQL, and it has no notion of a primary and a standby. Teams that arrive expecting those features are looking at the wrong project, and no amount of configuration will add them.
The second constraint is operational. Pooling changes the lifetime of a server connection, and transaction-level pooling in particular decouples a client session from a backend session. Anything that assumes session state persists between statements, such as session-level advisory locks, prepared statement caching tied to a backend, or temporary tables created outside a transaction, can behave differently once a pooler is in the path. The repository does not document these cases in the README, and the README does not document rollback behaviour for a pooler restart either, so treat them as things to test against your own workload rather than assume.
Finally, the build story itself is a cost. Autoconf is recommended for production today while Meson is still labelled experimental, which means packaging work will have to be revisited when the default flips. If you are not prepared to track that transition, a managed pooling service may be cheaper than owning the binary.
PgBouncer Compared with Pgpool-II
The comparison people reach for is Pgpool-II, and the difference is architectural rather than a matter of degree. PgBouncer is one process that owns a pool of server connections and does nothing else; it is written in C, depends on Libevent and OpenSSL, and its source tree is small enough to read through. Pgpool-II takes on a broader role, including query routing and replication coordination, which means it has to understand more of what flows through it.
That breadth is the trade-off. A pooler that only manages connections has fewer ways to surprise you and a smaller surface to keep patched, but it also cannot solve problems that live above the connection layer. If your requirement is read/write splitting across nodes, PgBouncer will not do it and Pgpool-II is aimed at that space. If your requirement is simply to stop opening a backend process per web request, the extra machinery is overhead you pay for without using.
Maintenance, Licensing and the Upgrade Path
The repository is not archived and the last push was on 2026-09-22, so the project is being worked on. Releases are tagged rather than continuous: 1.25.0 added LDAP support, 1.25.1 was described in its release notes as fixing a batch of bugs including CVE-2025-12819, and 1.25.2 followed in May 2026. That cadence suggests security fixes arrive as patch releases rather than being backported indefinitely, so running an older minor version is a deliberate risk.
The licence is reported by the repository metadata as NOASSERTION, which means GitHub could not map the licence file to a known identifier. The repository does carry a COPYRIGHT file and an AUTHORS file at the top level. That is enough to tell you a licence exists, and not enough to tell you what it permits. Read COPYRIGHT before you redistribute the binary or ship it inside a product; this is not something to infer from the metadata field.
Upgrade cost is mostly about build flags. Because Meson auto-detects PAM, LDAP and systemd while Autoconf requires explicit opt-in, two builds of the same version can differ in capability. If your configuration file references an authentication type that the binary was not compiled with, the failure will be at runtime rather than at configure time. Pin your build flags in whatever recipe produces the artifact.
Running the Test Suite Before You Trust a Build
The repository carries a test directory with its own README, and the top-level pyproject.toml exists solely to declare the Python tooling for it. There is no importable Python package; the file says the distribution is empty apart from its metadata and that pip install . installs the test tools while pip install .[dev] adds the linters.
The test dependencies are pytest, pytest-asyncio, pytest-timeout, pytest-xdist, psycopg and filelock, with ruff as the dev extra. Pytest is configured with a 30 second timeout, asyncio_mode set to auto, and a filterwarnings setting of error, which means warnings fail tests. There is also an md5 marker for tests that will fail in FIPS mode, which is a useful signal if your environment enforces FIPS.
pip install .
pytestRunning this against your own build is the cheapest way to confirm the binary behaves as the upstream project expects before you put it in front of production traffic.
Editorial conclusion
Adopt PgBouncer if you run many short-lived clients against one PostgreSQL server and want to cap backend connections without changing application code. Do not adopt it if you need query routing, read/write splitting or cross-node load balancing, because it is a pooler rather than a load balancer. Before you deploy, verify which DNS backend your build picked up, since c-ares is used by default when it can be found and the Meson build makes PAM, LDAP and systemd decisions at configure time.
Frequently asked questions
What is PgBouncer for?
It is a lightweight connection pooler for PostgreSQL. It accepts client connections and reuses a smaller set of server connections, which keeps PostgreSQL from forking a backend process for every client.
Is PgBouncer a load balancer?
No. It pools connections between clients and PostgreSQL; it does not route queries across nodes or split reads from writes. If you need that, a pooler is not the component you are looking for.
How do I install PgBouncer on Windows?
Build it with MinGW, which the README says is the only supported Windows build environment; Cygwin and Visual Studio are not supported. LDAP is not available on Windows, and the -d and -u switches do not work at runtime. To run it as a service, set service_name in the configuration file and run pgbouncer -regservice config.ini.
How do I install PgBouncer on Linux or Ubuntu?
The README documents building from source rather than a distribution package. With Autoconf you run ./configure --prefix=/usr/local, make, and make install; from a Git checkout you run ./autogen.sh first. The Meson build is available but still described as experimental.
What are the key differences between PgDog and PgBouncer?
The repository does not discuss PgDog, so there is nothing here to compare against. What the README does establish is PgBouncer's scope: it is a connection pooler, not a query router or load balancer.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pgbouncer-pgbouncer)