DB Connection Pools
A connection pool maintains a set of pre-established database connections that application threads reuse, avoiding the latency cost of creating new connections per request.
Connection pool = a valet parking lot with a fixed number of keys. Opening a new DB connection is like buying a new car for every trip -- just reuse the parked ones.
Creating a PostgreSQL connection takes 20–50ms (TCP handshake, TLS, auth). At 10k RPS, creating a new connection per request would be catastrophic. Connection pools (PgBouncer for PostgreSQL, HikariCP for Java) keep N persistent connections open and queue requests when all connections are busy. Pool size is critical: too small causes queuing; too large overwhelms the database (PostgreSQL has process-per-connection overhead, typically max 100–500 connections).
PostgreSQL's process-per-connection model means each connection uses ~5–10MB of RAM. With 500 connections, that's 2.5–5GB for connection overhead alone. PgBouncer in transaction-mode pooling multiplexes thousands of application connections over tens of database connections by releasing the DB connection back to the pool after each transaction. This enables cloud deployments with thousands of Lambda functions or serverless instances hitting the same database. Serverless architectures are particularly problematic: AWS Lambda can instantiate thousands of concurrent instances each trying to open a DB connection — use RDS Proxy or PgBouncer as a middleware pool. Pool sizing formula: pool_size = (core_count * 2) + effective_spindle_count (from PostgreSQL wiki).
I'd always run a connection pooler in front of PostgreSQL at any meaningful scale. PgBouncer in transaction mode is my default — it multiplexes thousands of app connections over a small pool of real DB connections. For serverless functions, I'd add RDS Proxy to prevent connection storms. I'd size the pool conservatively (50–100 DB connections) and monitor queue wait time as the key metric — if wait time rises, investigate query latency before increasing pool size.
Increasing connection pool size when the database is under load. If queries are slow, more connections just pile up waiting. Fix slow queries first; add connections only to prevent queuing of fast queries.