HikariCP Connection Pool Tuning That Won't Crash Your Database
Connection pool misconfiguration is the most common self-inflicted outage in database-backed services. Over-provisioning connections across multiple instances silently exhausts the database's session limit, while under-provisioning causes thread starvation that looks like a slow database but is actually a queueing problem in the app layer.
Default HikariCP settings get a Spring Boot app running but rarely survive real traffic. The pool size must be derived from the database's max_connections, the number of app instances, and the ratio of SQL time to total request time — not from a guess. A simple formula (target concurrency × DB time / total request time) produces a starting number that stress testing can validate.
Connection timeouts should force fast failure under congestion rather than letting threads hang; idle and max-lifetime values need to stay below any infrastructure-level disconnect thresholds. Enabling leak-detection-threshold in dev and test catches unclosed connections before they reach production, surfacing the exact call stack.
The pool doesn't operate in isolation. A Tomcat thread pool of 100 with only 10 Hikari connections starves 90 threads; 100 connections against a database capped at 100 leaves no headroom for other consumers. The article provides conservative starter configs for Windows dev (max 5 connections, leak detection at 10s), test (max 20), and a checklist for production tuning that begins with database session counts and ends with P95 latency.
The estimation formula (concurrency × DB time / total time) is a useful heuristic, but it assumes uniform request profiles; real workloads with mixed fast and slow queries will need headroom beyond the calculated number.
Fast-fail connection timeouts are a deliberate architectural choice that trades user-facing errors for system stability — it requires corresponding alerting and retry logic upstream, otherwise it just shifts the failure to the caller.
The advice to set max-lifetime below infrastructure disconnect thresholds is sound but often overlooked: cloud load balancers, firewalls, and managed database proxies all have their own idle-timeout defaults that can silently kill connections the pool still considers valid.