Connection Leaks in Database Connection Pools
A connection leak occurs when application code does not return a checked-out database connection to its pool. Leaks consume pool capacity and can cause requests to wait or time out.
A connection pool keeps database connections available for reuse. Application code checks out a connection for work and must return it when finished. A connection leak occurs when code fails to return a checked-out connection, often because cleanup is skipped on an error path or an early return.
Leaked connections remain unavailable to other requests. If enough connections are held, the pool can run out of available connections; requests may then wait for a checkout or fail after a timeout. This can look like a database outage even when the database itself is healthy.
Use the pool or framework’s supported lifecycle mechanism: a context manager, transaction scope, or `try/finally` cleanup. Make sure cleanup covers exceptions and early exits. The precise operation may be called `close`, `release`, or returned automatically by a context manager; follow the library’s documented behavior.
Diagnose suspected leaks by checking pool metrics such as checked-out, idle, and waiting counts, and by logging connection acquisition and release. Also investigate slow queries and work performed while holding a connection: these reduce availability but are not necessarily leaks.
Key points
- Return every checked-out connection, including on exceptions and early exits.
- Prefer pool or framework lifecycle constructs that guarantee cleanup.
- A leak reduces available pool capacity and can cause waits or timeouts.
- Use pool metrics and acquisition/release traces to investigate suspected leaks.
- Long-held connections can harm capacity without being permanent leaks.
Interview questions
What is a connection leak, and why is it a problem?
A connection leak is a checked-out connection that application code fails to return to its pool. Each leaked connection reduces the pool’s available capacity. If enough connections are lost, new requests may block while waiting for a connection or time out. I would verify the diagnosis with pool metrics and inspect all acquisition paths for matching cleanup.
How would you ensure a connection is returned when a database operation raises an exception?
I would use the library’s context manager or transaction scope when available, so cleanup runs when control leaves the block, including on exceptions. Otherwise, I would put release logic in a `finally` block that covers every path after acquisition. I would verify whether the library’s cleanup call returns the connection to the pool or has different semantics. Cleanup should not depend on the query succeeding.
How would you diagnose suspected connection leaks in a production service?
I would compare checked-out and idle connections over time, along with waiters and checkout timeouts. A steadily rising checked-out count that does not fall after requests complete suggests connections are not being returned; high checkout duration may instead point to slow queries or work done while holding connections. I would correlate acquisition and release logs or traces by request and connection identity. Then I would inspect error paths, cancellation handling, and background tasks, while checking database-side activity to distinguish application leaks from genuinely long-running work.
How is a connection leak different from holding a connection for a long time?
A leak means the connection is not returned as expected, whereas a long-held connection may eventually be returned but remains unavailable in the meantime. Both can increase checkout waits and reduce throughput. I would compare connection hold times with request and query timings, and inspect whether connections are held during unrelated work such as network calls. A rising checked-out count that persists after work finishes is stronger evidence of a leak than a high but bounded hold time.