How it works
The explanation, with examples you can run.
The settings that matter
spring: datasource: url: jdbc:postgresql://db:5432/shop hikari: maximum-pool-size: 10 # default 10; also the size, since minimum-idle defaults to it connection-timeout: 2000 # ms; default 30000: how long a caller waits for a free connection max-lifetime: 1500000 # ms (25 min); default 30 min: keep it below any database or proxy cut-off pool-name: shop-dbHikari's own advice is to leave minimum-idle unset, so the pool stays at a fixed size and never has to open connections during a spike. max-lifetime retires connections before a firewall or the database drops them silently; it should be a little shorter than any such limit.
How big?
It is tempting to match the pool to Tomcat's 200 threads. Hikari's sizing page argues the opposite. A database server with 4 cores can only execute a handful of queries truly at once; past that, extra connections add context switching and lock contention. Its starting formula is:
connections = (core_count x 2) + effective_spindle_countcore_count is the database server's physical cores, and effective_spindle_count is about 0 when the working set is cached (and has not been analysed for SSDs). For 4 cores that gives roughly 9 or 10, which is why 10 is a reasonable default. Treat it as a starting point and measure.
Remember the pool is per application instance. Ten replicas with 10 connections each is 100 connections on the database, and its max_connections is shared by everyone.
When the pool is the bottleneck
Usually it is not the size but how long connections are held:
- A transaction that calls a slow HTTP service keeps its connection the whole time.
- Open-session-in-view holds one until the response is written.
REQUIRES_NEWneeds a second connection while the first is still held. With every thread doing it at once, the pool can lock up completely; the Spring docs say such a pool must exceed the number of concurrent threads.
Seeing it
With Actuator, Boot publishes pool metrics with the hikaricp prefix (and generic jdbc.connections.* gauges):
| Metric | Tells you |
|---|---|
hikaricp.connections.active | Connections in use now |
hikaricp.connections.pending | Threads waiting for one |
hikaricp.connections.acquire | How long they waited |
hikaricp.connections.timeout | Callers that gave up |
A pending count above zero most of the time means requests are queuing for the database. Shorten what holds connections before raising the size, and set a connection-timeout that fails fast rather than parking threads for 30 seconds.
Follow the flow
Play it or step through. Pause and tap a box to see what it does.
Paused · tap a box to explore it
Three request threads share a pool of two connections. The pool is small to keep the picture simple; Boot's default is ten.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.