Detailed explanation
Connection pooling is the reuse of established database connections across application operations. In Java, an application typically obtains a JDBC Connection from a pooled DataSource rather than creating a physical connection for every request. Creating a connection can involve network communication, authentication, and database session setup. Reusing connections avoids repeatedly paying these costs, improving response time and reducing resource overhead on both the application and database servers.
Under the hood, a pool such as HikariCP manages physical connections and lends them to callers. Calling ds.getConnection() borrows an available connection, usually through a proxy. If none is available, the pool may create another connection within its configured limit; otherwise, the caller waits until a connection becomes available or the acquisition timeout expires. Calling close() on the borrowed Connection normally returns it to the pool instead of closing the underlying database session. Therefore, try-with-resources remains essential: try (Connection conn = ds.getConnection()) { ... } reliably releases the borrowed connection, including when an exception occurs.
Pooling is also a concurrency-control mechanism. A configured maximum pool size limits how many database connections an application instance can use, helping prevent uncontrolled connection growth under load. However, a larger pool is not automatically faster: excessive concurrent queries can increase database contention and reduce throughput. Sizing should consider database capacity, query duration, application concurrency, and the total number of application instances. Monitor active and idle connections, acquisition wait times, and timeouts, then validate settings with realistic load tests rather than choosing an arbitrary large number.
Production pools also validate connections and retire them according to lifetime and idle settings, replacing unusable connections when necessary. In the HikariCP example, configure the JDBC URL and required credentials before borrowing connections, and close the HikariDataSource during application shutdown. Keep transactions short, commit or roll back explicitly when managing transactions yourself, and avoid holding connections during unrelated work such as external API calls. Interviewers look for the distinction between logical close and physical close, reliable resource handling, and awareness that pooling cannot fix slow SQL or unlimited database demand.
Key points to remember
- Pooling reuses physical database connections, avoiding repeated connection setup costs.
- A pooled Connection.close() normally returns the connection to the pool; use try-with-resources.
- When the pool is exhausted, callers wait for a connection until the acquisition timeout expires.
- Pool size bounds connection concurrency and must account for all application instances.
- HikariCP manages connection acquisition, validation, and retirement; monitor its behaviour under load.
Common mistakes candidates make
- Not closing borrowed connections because the pool is assumed to handle their release automatically.
- Increasing pool size blindly without checking database limits, query performance, or acquisition wait times.
- Holding a connection during unrelated work or returning it without explicitly completing an application-managed transaction.
Likely follow-up questions
What happens if every connection in the pool is already borrowed?
The pool can create another connection if it is below its maximum size. At the limit, the caller waits; if no connection becomes available within HikariCP's connectionTimeout, acquisition fails with a SQLException.
How do you choose the maximum pool size?
Start with the database's connection budget and divide capacity appropriately across application instances and other clients. Tune using realistic load tests, observing database utilisation, throughput, and connection acquisition wait times.
Is connection pooling the same as sharing one Connection across threads?
No: a pool normally lends each connection exclusively to one borrower at a time. Sharing a borrowed Connection across concurrent requests risks interference through its transaction and session state.
Interview tip: Explain borrowing and returning first, show try-with-resources, and finish with the trade-off between connection reuse and database concurrency.
