Connection Pool
In short
A connection pool is a cache of open database connections that an application reuses across requests, avoiding the cost of opening a new connection every time.
What is a connection pool?
A connection pool is a set of database connections that an application opens ahead of time and keeps ready for reuse. When code needs to run a query, it borrows a connection from the pool, uses it, and returns it instead of closing it. The next request can then use the same connection right away.
Opening a database connection is expensive: it needs network round trips, often a TLS handshake, authentication, and memory on the database server for each session. A pool pays that cost once and shares connections across many requests. It is configured with settings such as a maximum size, a minimum number of idle connections, and a timeout for how long a request waits when every connection is busy.
Think of the shared bikes at a bike station: instead of building a new bike for every trip and throwing it away at the end, riders take one, ride, and put it back for the next person. Connection pools are built into most database drivers and ORMs, and standalone pooling proxies can sit between many application servers and the database. They are especially important for serverless functions, which may start many short-lived instances that would otherwise flood the database with connections.
A common misconception is that a bigger pool is always faster. Every database can handle only a limited number of connections efficiently, so a pool that is too large can slow everything down, while one that is too small makes requests wait in line. Another frequent bug is a connection leak, where code borrows a connection and never returns it, until the pool runs dry and the app stops responding.
Key takeaways
- A pool keeps database connections open and reuses them across requests.
- It avoids the slow setup of a new connection for every query.
- Key settings are the maximum size, idle connections, and wait timeout.
- Always return connections to the pool, or they will leak.
- Bigger is not always better, because the database can handle only so many connections.
Example
import pg from "pg";
// Create one pool when the app starts and share it everywhere
const pool = new pg.Pool({
connectionString: process.env.DATABASE_URL,
max: 10, // at most 10 open connections
idleTimeoutMillis: 30000, // close connections idle for 30 seconds
connectionTimeoutMillis: 2000, // give up if no connection is free in 2 seconds
});
// pool.query borrows a connection and returns it automatically
const { rows } = await pool.query("SELECT * FROM users WHERE id = $1", [42]);
console.log(rows[0]);Readers ask
Why use a connection pool?
Opening a new database connection for every request adds latency and puts extra load on the database. Reusing a small set of open connections makes queries start faster and keeps the number of connections under control.
How big should a connection pool be?
Usually smaller than people expect: start with a few connections per CPU core on the database server, then tune with load tests. Remember that the total across all application instances must stay below the database's connection limit.
What happens when all connections in the pool are busy?
New requests wait in a queue until a connection is returned. If none frees up before the configured timeout, the request fails with an error, which is often a sign of slow queries or a connection leak.
See also
- DatabaseDatabases, p. 6A database is an organized collection of data stored on a computer, managed by software that lets applications save, search, and update it efficiently.
- ORMDatabases, p. 33An ORM is a library that maps database tables to objects in your programming language, letting you read and write data with code instead of raw SQL.
- ServerlessDevOps & Cloud, p. 47Serverless is a cloud model in which the provider runs your code on demand, manages all the servers, scales automatically, and bills only for actual use.
- LatencyNetworking, p. 14Latency is the delay between sending a request and the start of a response, usually measured in milliseconds, and it shapes how responsive an app feels.
- Load TestingTesting & Quality, p. 15Load testing is a type of performance testing that simulates many users or requests at once to measure how a system behaves under expected traffic.
- TransactionDatabases, p. 47A transaction is a group of database operations that succeed or fail as a single unit, so the data is never left in a half-finished, inconsistent state.
Spotted a mistake or something missing on this page?Suggest an edit