ConnectionTimeoutException during concurrent request spikes in HikariCP
0 reputation · 17 Aug 2024, 15:01 UTC
0 reputation · 17 Aug 2024, 15:01 UTC
JHipster-generated Spring Boot applications rely on HikariCP for database connection pooling. Under high concurrency, the application may encounter a ConnectionTimeoutException when the number of active request threads exceeds the configured maximum-pool-size, causing threads to block until the connection-timeout threshold is reached.
While manual tuning of properties is possible, the default sizing in JHipster blueprints remains static and does not automatically scale based on the underlying container resource limits or hardware specifications.
What is the recommended strategy for balancing the maximum-pool-size to prevent timeout exceptions without introducing excessive context switching or database server resource contention? How can the pool be configured to scale dynamically relative to available system resources?
33775 reputation · 18 Aug 2024, 02:26 UTC
To prevent ConnectionTimeoutException without overwhelming the database server, avoid the instinct to simply increase maximum-pool-size to match your peak request thread count. Doing so often leads to database CPU contention and excessive context switching, which actually increases the time a connection is held, worsening the timeout problem.
The industry-standard starting point for sizing a HikariCP pool is based on the database server's hardware capacity rather than the application's request volume:
connections = ((core_count * 2) + effective_spindle_count)
Where core_count is the number of CPU cores on the database server and effective_spindle_count represents the number of disks in a RAID array (or a similar factor for SSD throughput). This formula ensures the database can actually process the concurrent queries without spending more time managing threads than executing SQL.
HikariCP does not natively support dynamic scaling of the maximum-pool-size based on system resources. The pool size is intended to be a static ceiling to protect the database from crashing under load. If you require a pool that adjusts to available resources, you must implement an external management layer using JMX (Java Management Extensions) to programmatically update the pool configuration at runtime.
maximum-pool-size.max_connections setting is higher than the sum of all maximum-pool-size values across all application instances.connection-timeout to a value that fails fast (e.g., 5000ms to 30000ms) to prevent request threads from piling up and exhausting application memory.ActiveConnections and PendingThreads. If PendingThreads is consistently high while ActiveConnections is at the limit, you have a genuine bottleneck.To verify if the bottleneck is the pool size or the database performance, compare these two indicators during a spike:
ConnectionTimeoutException, but the database server shows low CPU usage and few active sessions.Missing Diagnostic Detail: Are you using a synchronous blocking architecture (Standard Spring MVC) or a non-blocking architecture (Spring WebFlux)? The recommendation for pool sizing differs significantly if the application is not tying one request thread to one database connection.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.