Kingsfordweg 151, 1043GR Amsterdam, The Netherlands ● 24/7 support — support@novogara.com
Knowledge base

Connection pooling for databases

Opening a database connection is cheap once and expensive ten thousand times. A pooler sits between your application and the database and turns a flood of short connections into a handful of reused ones.

Every database connection costs memory and setup time. Web applications love to open one per request and throw it away — multiply that by concurrency and the database spends its life making and breaking connections instead of answering queries. A pooler fixes that.

What it does

The pooler — PgBouncer for PostgreSQL, ProxySQL for MySQL — keeps a small set of real database connections open and hands them out to many application connections as needed. The application thinks it has thousands of connections; the database sees a few dozen.

Pool modes matter

  • Session — a client keeps its connection for its whole session. Safe, least sharing.
  • Transaction — a connection is returned after each transaction. The sweet spot for web apps.
  • Statement — returned after every statement. Maximum sharing, but breaks anything using transactions.

Transaction mode is what most web applications want — but it forbids session-level features like prepared statements held across transactions. Know what your framework assumes.

Size the pool to the database, not the app

The pool size should match what the database can actually handle well — often far fewer connections than you expect. A pool of 20–40 busy connections serving thousands of clients outperforms a direct free-for-all. This pairs directly with keeping max_connections low in PostgreSQL.

It is one more thing to watch

The pooler is now in the path of every query. Monitor it, give it its own place to run, and understand that if it is down, the database is effectively unreachable — see monitoring.


Still stuck? Mail support@novogara.com — an engineer answers, at any hour. Back to the knowledge base