Backend & Node.js · APIs, data and failure
Why is database connection pooling important?
Short answer
Opening a database connection is expensive, so a pool reuses a bounded set across requests. It controls concurrency and protects the database, but too small a pool queues requests and too large a pool overwhelms the server.
A connection involves a TCP handshake, authentication and session setup. Creating one per request adds latency and consumes server memory. A pool keeps idle connections ready and hands them to callers, then returns them when the work finishes.
const pool = new Pool({
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
const client = await pool.connect();
try {
await client.query("BEGIN");
await client.query("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
await client.query("COMMIT");
} catch (error) {
await client.query("ROLLBACK");
throw error;
} finally {
client.release();
}Sizing and failure modes
- Total connections across all instances must stay below the database limit
- A pool per process multiplies connections when you scale replicas
- An external pooler such as PgBouncer can multiplex many clients onto fewer server connections
- Serverless functions need a pooler or a managed proxy because instances are short-lived
- Long transactions hold a connection and reduce effective capacity
- Set a connection timeout so requests fail fast instead of hanging
Sizing is a trade-off, not a formula. Start from the database's comfortable concurrency and divide by the number of application instances. Monitor pool wait time and active connections; if wait time rises while the database is not saturated, the pool may be too small or connections may be leaked.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What happens when the pool is exhausted?
- 2How does PgBouncer change connection management?
- 3Why is pooling difficult in serverless?
- 4How do you detect a leaked connection?
Say it in the interview
Connections are expensive to establish, so a pool reuses a bounded set and protects the database from connection floods. Sizing has to account for every application replica, because each process has its own pool. If the pool is too small, requests queue; if it is too large, the database runs out of connections or memory. I monitor wait time and active connections, and I always release the client in a finally block.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Backend & Node.js mock interview and get scored feedback on depth, clarity and confidence.