Connection Pool
A connection pool is a managed set of pre-established connections (to a database, cache, or external service) reused across requests instead of created and destroyed each time. Pooling slashes latency and resource consumption in high-throughput applications.
Why Connection Pools Matter
Establishing a new database connection is expensive — TCP handshake, Transport Layer Security (TLS) negotiation, and authentication can take 50-200ms. Without a pool:
- Every request pays the connection setup cost
- Under load, you can exhaust the database’s maximum connections
- Connection storms during traffic spikes can crash your database
With a pool, connections are created once and reused thousands of times over.
How a Connection Pool Works
- The pool creates a set of connections at startup (or lazily on first use)
- When a request needs a connection, it borrows one from the pool
- When the request is done, the connection is returned to the pool (not closed)
- If all connections are in use, new requests wait in a queue
// Without pool: new connection per request (~100ms overhead)
app.get('/api/data', async (req, res) => {
const client = new Client(DATABASE_URL);
await client.connect();
const result = await client.query('SELECT ...');
await client.end();
res.json(result.rows);
});
// With pool: reuses connections (~0ms overhead)
const pool = new Pool({ connectionString: DATABASE_URL, max: 20 });
app.get('/api/data', async (req, res) => {
const result = await pool.query('SELECT ...');
res.json(result.rows);
});
Pool Configuration
| Setting | What It Controls | Typical Value |
|---|---|---|
| max | Maximum connections in the pool | 10–50 |
| min | Minimum idle connections kept open | 2–5 |
| idleTimeoutMillis | How long an unused connection stays open | 10,000–30,000 |
| connectionTimeoutMillis | How long to wait for a free connection | 5,000–10,000 |