The Problem
Your application is gasping for a database connection, but the pool is dry. Every single connection is currently busy. By default, HikariCP waits for 30 seconds (30,000ms) for a connection to return to the pool. If that window closes and nothing becomes available, your app throws the SQLTransientConnectionException and the request fails.
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:696)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:197)
Why Connections Run Out
- Leaky Code: Connections are borrowed but never returned to the pool, often due to missing
finallyblocks in legacy JDBC code. - Bottleneck Queries: A few queries taking 5โ10 seconds each can quickly saturate a small pool.
- Under-provisioned Pool: You are using the default size of 10 connections, but your traffic requires 25.
- Transaction Bloat: Holding a database connection while waiting for a slow 3rd-party REST API to respond.
Solution 1: Detect and Plug Connection Leaks
Leaks are the primary reason pools stay exhausted even during low traffic. While Spring Data JPA handles most of this for you, custom JDBC logic often misses a close command. HikariCP has a built-in detective to find exactly where the leak starts.
Add this property to your application.properties:
# If a connection is out for more than 2 seconds, log a stack trace
spring.datasource.hikari.leak-detection-threshold=2000
With this setting active, your logs will pinpoint the specific method that borrowed the connection. Look for the message "Apparent connection leak detected" followed by a stack trace. Fix the code, and the error should vanish.
Solution 2: Right-Size Your Pool
The default pool size of 10 is quite conservative. For a production microservice under moderate load, you might need to bump this up. However, avoid the temptation to set this to a massive number like 500; your database CPU will likely choke on the context switching.
# Increase the max connections based on your DB hardware (e.g., 20-50)
spring.datasource.hikari.maximum-pool-size=30
# Keep a few connections ready to go
spring.datasource.hikari.minimum-idle=10
# How long a client waits before giving up (30s is usually fine)
spring.datasource.hikari.connection-timeout=30000
Note: Always verify your database server's capacity. If you have 5 instances of your app each set to a maximum-pool-size of 30, your database must be able to handle at least 150 concurrent connections.
Solution 3: Decouple Transactions from External I/O
One of the most frequent mistakes is wrapping an entire service method in @Transactional when it performs network calls. If a remote API takes 5 seconds to respond, your database connection sits idle and useless for those 5 seconds.
The Wrong Way:
@Transactional
public void completePurchase(Order order) {
orderRepo.save(order); // Connection acquired here
// DANGER: Connection is held while waiting for the payment gateway
paymentService.chargeCreditCard(order.getAmount());
orderRepo.updateStatus(order, "PAID");
} // Connection finally released here
The Right Way: Keep your transactions lean. Perform the database write, commit it, call your API, and then start a second transaction to update the status. This frees up the connection for other users while the API call is in flight.
Solution 4: Monitor Pool Health
Stop guessing and start measuring. By using Spring Boot Actuator, you can see exactly how many connections are active or pending in real-time. Add the following to your pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Enable the metrics in your config:
management.endpoints.web.exposure.include=metrics
management.endpoint.metrics.enabled=true
Check the /actuator/metrics/hikaricp.connections.pending endpoint. If the 'pending' count is consistently higher than 0, it is a clear signal that your pool is too small or your queries are too slow to keep up with demand.

