HN Debrief

Does anyone run Postgres without PgBouncer?

  • Databases
  • Infrastructure
  • Open Source
  • Cloud
  • Developer Tools

The post argues that if so many PostgreSQL deployments need PgBouncer, connection pooling should feel like core database functionality instead of a sidecar. PgBouncer exists to hide one of Postgres’ oldest tradeoffs: each client connection maps to a heavyweight backend process, so too many concurrent or short-lived connections burn memory and create churn. The comments landed on a much narrower answer than the title suggests. Plenty of teams run Postgres directly in production, especially with a small number of long-lived app servers, built-in app pools, or B2B and on-prem workloads where user counts stay bounded. In that shape of system, PgBouncer is just another moving part.

Treat PgBouncer as a scaling tool for connection churn and shared multiplexing across many app instances, not as mandatory PostgreSQL boilerplate. If your fleet is growing horizontally, using serverless, or struggling with idle connection waste, add it deliberately and audit session-level features before you flip transaction pooling on.

Discussion mood

Mostly dismissive of the post's framing but favorable to the core complaint that connection pooling feels too essential to live outside Postgres. The dominant view was that PgBouncer is useful and common, especially for serverless and horizontally scaled fleets, but far from universally required and often added prematurely.

Key insights

  1. 01

    LIFO pooling cuts idle connection waste

    PgBouncer is useful because it optimizes for fewer live database backends, not just faster checkout latency. The key point is its last-in-first-out reuse pattern, which keeps hot connections busy and lets excess ones go cold and close. Typical app pools often keep every slot warm, which is fine inside one process but wasteful once many replicas each maintain their own mostly idle pool.

    Look past raw pool size settings and inspect how your pool retires idle connections. In a multi-instance deployment, a pooling strategy that shrinks aggressively can save more Postgres capacity than simply lowering per-instance limits.

      Attribution:
    • giovannibonetti #1
  2. 02

    App pools cannot share across replicas

    The hard limit with app-side pooling is that every pod or worker owns its own pool. Even if each pool is well tuned, idle capacity trapped in one replica cannot be used by another, so horizontal scaling quietly turns into a large number of mostly wasted Postgres backends. An external pooler fixes a different problem than a driver pool because it multiplexes across the whole fleet.

    When you scale out with pods, workers, or multiple services, count total idle connections across the fleet, not just active traffic. If that number is large, PgBouncer or a similar shared pooler is solving a real systems problem your driver cannot.

      Attribution:
    • atombender #1
    • aobdev #1 #2
  3. 03

    Transaction pooling breaks session assumptions

    The real operational risk is not learning one more component. It is forgetting that transaction pooling swaps backend sessions between transactions. That can break session-scoped SET usage, search_path expectations, prepared statement behavior in drivers like psycopg3, and other features that assume a stable backend. Commenters noted this has improved over time, but it is still the main reason PgBouncer is not a drop-in default for every app.

    Before enabling transaction mode, test your exact driver, ORM, and feature usage against session loss. Put prepared statements, session variables, and any use of LISTEN or advisory state on a checklist instead of assuming your integration is safe.

      Attribution:
    • saadyousfi #1
    • zzzeek #1
    • saisrirampur #1
  4. 04

    Long transactions defeat the point

    PgBouncer only helps when it can interleave short units of work over a smaller set of backend sessions. If your requests hold transactions open for a long time, the queue just moves from Postgres to the pooler. That means the bottleneck is transaction duration, lock time, or application flow, not connection establishment.

    If you already see long-running transactions, fix them before adding a pooler. Otherwise you will add another queue and still hit the same throughput ceiling.

      Attribution:
    • tyre #1
  5. 05

    Bad framework patterns create fake demand

    Some teams reach for PgBouncer because their framework usage is tying up connections unnecessarily. One example called out FastAPI dependency-injected transactions that leave sessions open through request handling and create idle transaction spam. In those cases, the pooler masks misuse of database connections instead of solving a real scaling need.

    Profile connection lifetime in your app before adding infrastructure. If connections sit idle inside request handlers or background jobs, changing framework patterns can remove the pressure more cleanly than adding PgBouncer.

      Attribution:
    • frollogaston #1

Against the grain

  1. 01

    Commercial databases solved this years ago

    Several comments argued the complaint is really about PostgreSQL lagging established enterprise databases. Oracle Database was cited as having built-in server-side pooling, client-side load balancing, failover, and horizontal scaling that make the “single URL that just scales” experience normal rather than an add-on. That framing flips the usual startup assumption that Pg plus sidecars is the practical default and suggests teams may be accepting real database limitations because open source has become the cultural baseline.

    If database reliability and scaling are strategic to your product, price alternatives against the full cost of Postgres plus proxies, outages, and engineering time. Even if you stay on Postgres, this comparison gives you a more honest picture of what functionality you are rebuilding around it.

      Attribution:
    • mike_hearn #1 #2
  2. 02

    Driver-layer pooling avoids PgBouncer compromises

    A different objection came from comments pointing to DataDirect's PostgreSQL drivers, which pool and handle failover in the connectivity layer while preserving a real backend session for the application. The point is not that DataDirect is broadly preferable, but that PgBouncer's biggest tradeoff comes from transaction-level backend swapping. If you need session semantics intact, there are architectures besides “direct to Postgres” or “PgBouncer in transaction mode.”

    If session affinity is essential and you still need pooling or failover features, evaluate driver-level options and session-mode designs instead of forcing transaction pooling. The right abstraction layer depends on which Postgres semantics your app cannot afford to lose.

      Attribution:
    • root-parent #1 #2

In plain english

B2B
Business-to-business, meaning software sold to other companies rather than individual consumers.
Kubernetes
An open source system for deploying and managing containerized applications across clusters of machines.
LISTEN/NOTIFY
A PostgreSQL feature for lightweight pub-sub messaging where clients listen for and receive notifications from the database.
PgBouncer
A lightweight proxy for PostgreSQL that pools and reuses database connections so many clients can share fewer backend connections.
pod
The basic deployable unit in Kubernetes, usually one or more containers that run together.
Postgres
PostgreSQL, a widely used open source relational database.
psycopg3
A widely used Python PostgreSQL driver.
search_path
A PostgreSQL setting that controls which database schemas are searched when object names are referenced without qualification.
serverless
A cloud model where the provider runs code and manages infrastructure automatically, often charging only for actual usage.
SET
A PostgreSQL command used to change session settings such as search_path or time zone for the current database session.

Reference links

Connection pooling tools and alternatives

Managed database and cloud references

Related Hacker News and blog references