Your Spring Boot app is humming along, then at peak traffic the logs fill with:
HikariPool-1 - Connection is not available, request timed out after 30000ms.
java.sql.SQLTransientConnectionException
The instinct is to bump maximum-pool-size and move on. That's usually the wrong fix — and you can see why if you can watch the pool actually run. So I built a simulator that does exactly that, in the browser.
▶ Live demo: https://dev48v.github.io/hikaricp-pool/
Source: https://github.com/dev48v/hikaricp-pool
What a connection pool actually does
A connection pool keeps a set of open database connections so each request doesn't pay the TCP + auth handshake. HikariCP's model, which the demo animates:
- A request (thread) borrows a connection, runs its query, and returns it.
- The pool creates connections lazily, up to
maximumPoolSize. - When every connection is busy, a new request does not fail immediately — it waits in a FIFO queue for one to be returned.
- If it waits longer than
connectionTimeout(default 30s), it gives up withSQLTransientConnectionException.
Hit burst ×15 on a pool of 10 in the demo: 10 connections go active, and 5 threads land in the wait queue with a live countdown. As queries finish, waiters are handed the freed connection.
Why "make the pool bigger" is the wrong reflex
Here's the part the simulator makes obvious. Push the query time up to 2000ms and drop connectionTimeout to 900ms, then burst. Now the connections are held longer than a waiter is willing to wait, so the queue drains straight into timeouts — no matter how the requests arrive.
The bottleneck isn't the number of connections. It's how long each one is held. Little's Law makes it precise:
required connections ≈ throughput (req/s) × mean hold time (s)
A pool of 10 with 5ms queries serves 2000 req/s. The same pool with one accidental 2-second query (a missing index, an N+1, a slow downstream call) serves 5 req/s before it saturates. Adding connections just moves the congestion onto the database — and a database has far fewer cores than you think, so a bigger pool often makes latency worse. The HikariCP authors famously recommend pools far smaller than people expect: often cores × 2 range, not hundreds.
The real fixes, in order
-
Find the slow query holding connections. Turn on
leakDetectionThresholdand look at what's still checked out. - Shorten hold time — add the index, kill the N+1, move slow external calls off the request thread.
- Then, maybe tune pool size — and usually down, not up.
Play with the three sliders (pool size, query time, timeout) and watch served vs timeouts and the wait queue. Once you've seen hold-time saturate a pool, that production error message reads completely differently.
If this made pool exhaustion click, a star helps others find it: https://github.com/dev48v/hikaricp-pool
Top comments (0)