PgBouncer is entirely optional and it's not always the right choice. If you have a classical app (non serverless) and you can maintain a connection pool from your app, then I recommend avoiding pgbouncer.
The benefits of pgbouncer mostly come from irregular client connections (too many, too much churn). If you don't have that problem, go direct to postgres.
I'm exploring replacing pgbouncer with an alternative (maybe home grown) at the moment. Mostly for multi-tenancy and HA reasons. Pgbouncer has been good for us, but it's limited in how we can deploy it in a multi-tenant environment.
This question will get more interesting responses if it was qualified as:
"Does anyone run Postgres without PgBouncer for non-trivial workloads?"
Because, as we can see from the comments so far, lots of people are going to say you don't need it for your blog that gets 10 hits a month.
I've personally never heard of anyone not using PGbouncer, or some connection pooling proxy, for reasonably concurrent workloads. PG's process-per-connection architecture almost requires it. Otherwise even a small connection storm will wreak havoc on your server.
Python: absolutely necessary due to the amount of processes and various deployments to run an application once it grows.
Java: never felt the need even on quite big apps. As it's much easier to share a connection pool locally, it's not as many single connections across the whole app.
If you don’t use serverless but instead a few (vertically scaling) servers, and your ORM / query builder supports pooling (all node libraries I’ve used have a pooler)…
Having a setup with just a simple docker deploy, running a monolith, not using pgbouncer so you can use LISTEN/NOTIFY to implement your own job queue:
I’d argue this is not the right question. Obviously people use Postgres without PgBouncer. If you include non-production in the mix (CI/CD), most connections probably avoid it.
But because PgBouncer is so common, the question should probably be, why isn’t connection pooling part of Postgres out of the box? I think this might be the more interesting question.
I wouldn't do it without pgbouncer. Asking for trouble when one day connections exceeds. It's just that you start with "oh I'll manage the pool from my app" and then you're stuck with either putting things into the app or tuning the pool for the other side-programs you need from the app.
Every single connection to Postgres is a new process, which requires a fork and new memory allocation (at least 10MB plus whatever you need for your query).
PgBouncer opens a pool of connections and then reuses them each time a client asks for a connection. This reduces latency (no more fork) and overhead (reuse memory).
What pgbouncer does is indeed core functionality. Compare Postgres to MySQL and sql server, where analogous standalone connection pools are rarely used. The fundamental reason pgbouncer needs to exist is Postgres’ utterly retrograde design. Other examples: xid wraparound, conflict with recovery, lack of undo space.
I mean… my self hosted Postgres with its ca 15 active connections certainly doesn't use PgBouncer, and it doesn't need to. But that was presumably not the intended scope of the question?
Then again, people forget you can just run your own Postgres (or anything really).
of course, the vast, vast majority of PostgreSQL users outside of managed cloud hosting are not using pgbouncer. pgbouncer introduces complexities into the database conversation (transaction-level pooling interacting with the prepared statement cache is a long recurring nightmare for us at sqlalchemy) that often not worth the complexity for small local installations.
this article seems to be talking about commercial cloud managed PG services, which yes, those absolutely need to support connection pooling and of course they're going to use pgbouncer.
DataDirect is not free but I guess we are discussing technical merits here. For them pooling happens in the connectivity layer and exposes proper pool controls such as minimum and maximum pool size, connection lifetime behavior, and optional connection state reset.
More importantly, it has capabilities that PgBouncer is not designed to provide. It can maintain alternate PostgreSQL servers, retry connections, randomize connection attempts across primary/alternate servers, and has explicit failover modes. The application retains a real PostgreSQL session while the driver handles connection reuse and failure handling.
That matters because of PgBouncer big technical compromise that is transaction pooling.
This breaks the assumption that one client connection is the PostgreSQL backend session.
Consequently, several session scoped PostgreSQL features do not work normally in transaction pooling. PgBouncer own compatibility table, lists some of the limitations:
https://www.pgbouncer.org/features.html
DataDirect does not need to solve that particular problem because its architecture does not perform that same transaction level back end swapping.
(I work on the postgres proxy layer at Neon)
PgBouncer is entirely optional and it's not always the right choice. If you have a classical app (non serverless) and you can maintain a connection pool from your app, then I recommend avoiding pgbouncer.
The benefits of pgbouncer mostly come from irregular client connections (too many, too much churn). If you don't have that problem, go direct to postgres.
I'm exploring replacing pgbouncer with an alternative (maybe home grown) at the moment. Mostly for multi-tenancy and HA reasons. Pgbouncer has been good for us, but it's limited in how we can deploy it in a multi-tenant environment.
This question will get more interesting responses if it was qualified as:
"Does anyone run Postgres without PgBouncer for non-trivial workloads?"
Because, as we can see from the comments so far, lots of people are going to say you don't need it for your blog that gets 10 hits a month.
I've personally never heard of anyone not using PGbouncer, or some connection pooling proxy, for reasonably concurrent workloads. PG's process-per-connection architecture almost requires it. Otherwise even a small connection storm will wreak havoc on your server.
Python: absolutely necessary due to the amount of processes and various deployments to run an application once it grows.
Java: never felt the need even on quite big apps. As it's much easier to share a connection pool locally, it's not as many single connections across the whole app.
Yes. Sometimes PostgreSQL is overkill for a low traffic, simple application. PgBouncer would be even more overkill and add unnecessary complexity.
If you don’t use serverless but instead a few (vertically scaling) servers, and your ORM / query builder supports pooling (all node libraries I’ve used have a pooler)…
Having a setup with just a simple docker deploy, running a monolith, not using pgbouncer so you can use LISTEN/NOTIFY to implement your own job queue:
https://www.dbos.dev/blog/postgres-listen-notify-scalability
This gives me warm fuzzy feelings, also making me relatively cloud-agnostic in the process, even though devops is not my strong point.
Most projects I do don’t need something more complex or vendor locked-in than this.
I guarantee you the vast majority of RDS instances aren't using RDS Proxy. For one, it's rather expensive.
I’m curius about pgcat, is there anyone here using it ?
I’d argue this is not the right question. Obviously people use Postgres without PgBouncer. If you include non-production in the mix (CI/CD), most connections probably avoid it.
But because PgBouncer is so common, the question should probably be, why isn’t connection pooling part of Postgres out of the box? I think this might be the more interesting question.
I wouldn't do it without pgbouncer. Asking for trouble when one day connections exceeds. It's just that you start with "oh I'll manage the pool from my app" and then you're stuck with either putting things into the app or tuning the pool for the other side-programs you need from the app.
For sure. I mean: many – if not most – people?
In my case, with Go, I have always relied on http://github.com/jackc/pgx pool, which works quite well, especially with the binary protocol.
I currently run without pgbouncer, but I have at most 200 connections. 50 of them are just replication. I didn't want the complexity.
Yes, I don't always need it. Depends on the service architecture.
Yes. I've never even heard of PgBouncer.
This is the first time I've heard pgbouncer mentioned in 15 years. I didn't know it was still around.
Me too. I even opened the page and I'm not sure of what's the problem being solved.
Every single connection to Postgres is a new process, which requires a fork and new memory allocation (at least 10MB plus whatever you need for your query).
PgBouncer opens a pool of connections and then reuses them each time a client asks for a connection. This reduces latency (no more fork) and overhead (reuse memory).
If it's designed well, your application also opens a pool of connections and re-uses them each time the code needs a DB connection.
PgBouncer? Don't even know er.
A whole bunch of Cloudflare clients run Postgres (self hosted) without pgbouncer (they use hyperdrive).
Yes
What pgbouncer does is indeed core functionality. Compare Postgres to MySQL and sql server, where analogous standalone connection pools are rarely used. The fundamental reason pgbouncer needs to exist is Postgres’ utterly retrograde design. Other examples: xid wraparound, conflict with recovery, lack of undo space.
Yes.
I mean… my self hosted Postgres with its ca 15 active connections certainly doesn't use PgBouncer, and it doesn't need to. But that was presumably not the intended scope of the question?
Then again, people forget you can just run your own Postgres (or anything really).
of course, the vast, vast majority of PostgreSQL users outside of managed cloud hosting are not using pgbouncer. pgbouncer introduces complexities into the database conversation (transaction-level pooling interacting with the prepared statement cache is a long recurring nightmare for us at sqlalchemy) that often not worth the complexity for small local installations.
this article seems to be talking about commercial cloud managed PG services, which yes, those absolutely need to support connection pooling and of course they're going to use pgbouncer.
Yes, except for serverless backend, you normally don't need it.
pgdog.
Are you kidding me? Have you heard about Data Direct?
https://docs.progress.com/bundle/datadirect-postgresql-odbc-...
DataDirect is not free but I guess we are discussing technical merits here. For them pooling happens in the connectivity layer and exposes proper pool controls such as minimum and maximum pool size, connection lifetime behavior, and optional connection state reset.
More importantly, it has capabilities that PgBouncer is not designed to provide. It can maintain alternate PostgreSQL servers, retry connections, randomize connection attempts across primary/alternate servers, and has explicit failover modes. The application retains a real PostgreSQL session while the driver handles connection reuse and failure handling.
That matters because of PgBouncer big technical compromise that is transaction pooling. This breaks the assumption that one client connection is the PostgreSQL backend session.
Consequently, several session scoped PostgreSQL features do not work normally in transaction pooling. PgBouncer own compatibility table, lists some of the limitations: https://www.pgbouncer.org/features.html
DataDirect does not need to solve that particular problem because its architecture does not perform that same transaction level back end swapping.