Database connections are expensive to open, so Spring Boot pools them with HikariCP by default. When throughput stalls under load, an undersized or misconfigured pool is a frequent — and invisible — culprit.
The key settings
Most tuning happens through a handful of properties. Boot maps them straight from
application.properties.
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.idle-timeout=600000Bigger is not better
More connections than the database can serve just moves contention from your app
to the database. A common starting formula is connections = (cores * 2) + disks,
then measure.
@Bean
public MeterBinder hikariMetrics(HikariDataSource ds) {
return registry -> ds.setMetricRegistry(registry);
}Exposing pool metrics lets you watch active vs. idle connections and pending threads waiting for a connection.
Fail fast, don't hang
A short connection-timeout means a request fails quickly when the pool is
exhausted, instead of piling up threads that block indefinitely.
Takeaways
- The pool, not the CPU, is often the limit under database-heavy load.
- Oversizing the pool pushes contention onto the database — size deliberately.
- Keep
connection-timeoutshort so exhaustion fails fast and visibly.
Set max-lifetime a little below your database's own connection timeout so the
pool retires connections before the server drops them.