Home/Learn/Spring Boot/Connection Pool — HikariCP

Connection Pool — HikariCP

Intermediate
Data Access

Spring Boot auto-configures HikariCP as the default connection pool; tuning maximumPoolSize, connectionTimeout, and keepaliveTime is critical for production.

Overview

HikariCP is Spring Boot's default JDBC connection pool — chosen for its low overhead (~50 μs acquire time) and small footprint. A connection pool maintains a set of pre-established DB connections and lends them to application threads on demand, avoiding the cost of TCP handshake + TLS + DB authentication on every query. The most critical tuning decision is `maximumPoolSize`: set it too low and requests queue up; set it too high and you overwhelm the DB (each PostgreSQL connection consumes ~5–10 MB). The Hikari team's rule of thumb: `pool_size = (number_of_cores * 2) + effective_spindle_count`, typically 10–20 for most services. `connectionTimeout`, `idleTimeout`, `maxLifetime`, and `keepaliveTime` handle stale connections.

Key Configuration Properties

`maximumPoolSize` is the most important parameter — it caps the total concurrent DB connections. `minimumIdle` controls how many connections are kept warm when the pool is idle (set equal to `maximumPoolSize` to disable dynamic sizing and avoid cold-start latency). `connectionTimeout` is how long a thread waits for a connection from the pool before throwing `SQLTimeoutException`.

Spring Boot — HikariCP key properties
# application.properties — HikariCP tuning
spring.datasource.hikari.maximum-pool-size=20       # max concurrent connections
spring.datasource.hikari.minimum-idle=20            # keep pool warm (= max for fixed pool)
spring.datasource.hikari.connection-timeout=30000   # 30s wait for connection from pool
spring.datasource.hikari.idle-timeout=600000        # 10min: release idle connections
spring.datasource.hikari.max-lifetime=1800000       # 30min: max connection age (rotate before DB server times out)
spring.datasource.hikari.keepalive-time=60000       # 1min: ping idle connections to prevent firewall drops
spring.datasource.hikari.pool-name=OrderDB-Pool     # name shown in JMX/logs

# Validate configuration at startup
spring.datasource.hikari.initialization-fail-timeout=1  # fail fast if DB unreachable

Sizing the Pool and Diagnosing Exhaustion

Pool exhaustion (all connections in use) causes request threads to queue at `connectionTimeout`. Symptoms: slow responses, `SQLTimeoutException` errors, high `hikaricp_pending_threads` metric. Root causes: too-low `maximumPoolSize`, slow queries holding connections too long, N+1 queries, or missing indexes. Diagnose with the HikariCP Prometheus metrics exposed by Micrometer.

HikariCP — pool exhaustion metrics and sizing formula
# Prometheus metrics via Micrometer (spring-boot-actuator + micrometer-registry-prometheus)
hikaricp_connections_active         # currently in use
hikaricp_connections_idle           # available
hikaricp_connections_pending        # threads waiting → alert if > 0 for > 5s
hikaricp_connections_timeout_total  # total exhaustion events since start
hikaricp_connections_max            # maximumPoolSize

# Grafana alert rule
- alert: HikariPoolExhaustion
  expr: hikaricp_connections_pending{pool="OrderDB-Pool"} > 0
  for: 10s
  annotations:
    summary: "HikariCP pool exhausted — increase maximumPoolSize or optimise queries"

# Formula for maximumPoolSize (Hikari team recommendation):
# pool_size = (core_count * 2) + effective_spindle_count
# e.g. 4 cores, 1 SSD → (4 * 2) + 1 = 9, round up to 10

Connection Validation and Stale Connections

Connections can go stale when a firewall or the DB server closes them while they are idle in the pool. `keepaliveTime` pings idle connections; `maxLifetime` forces rotation before the DB server's `wait_timeout` closes them. Always set `maxLifetime` to slightly less than the DB server's connection timeout. `connectionTestQuery` (or the JDBC4 `isValid()`) validates connections on acquisition.

HikariCP — stale connection prevention config
# Prevent stale connections
spring.datasource.hikari.max-lifetime=1800000       # 30min (< MySQL wait_timeout of 8h default)
spring.datasource.hikari.keepalive-time=60000       # ping every 60s when idle

# For MySQL: ensure maxLifetime < wait_timeout
# Check: SHOW VARIABLES LIKE 'wait_timeout';   (default: 28800 = 8h)
# Set: spring.datasource.hikari.max-lifetime=1740000  (29min < 30min wait_timeout if custom)

# JDBC4+ (Postgres, MySQL 5.6+): isValid() used automatically — no connectionTestQuery needed
# For older JDBC3 drivers:
spring.datasource.hikari.connection-test-query=SELECT 1

# Multiple DataSources (e.g. primary + read-replica)
@Bean
@Primary
@ConfigurationProperties("spring.datasource.primary.hikari")
HikariDataSource primaryDataSource() { ... }

@Bean
@ConfigurationProperties("spring.datasource.replica.hikari")
HikariDataSource replicaDataSource() { ... }

Key Points to Remember

  • 1HikariCP is Spring Boot's default pool — ~50 μs acquire time, minimal overhead
  • 2maximumPoolSize is the most critical tuning knob — too low queues requests, too high overwhelms the DB
  • 3Set minimumIdle = maximumPoolSize for a fixed pool with no cold-start latency
  • 4maxLifetime must be less than the DB server's wait_timeout to prevent stale connections
  • 5keepaliveTime pings idle connections to prevent firewall/NAT dropping them
  • 6Monitor hikaricp_connections_pending — non-zero means pool exhaustion; tune size or fix slow queries

Interview Questions

Sign in to ask Aria
1

What happens when all HikariCP connections are in use and a new request arrives?

EasyAmazon
2

How would you size the maximumPoolSize for a service running on 4-core nodes?

MediumThoughtWorks
3

What is a stale connection and how does maxLifetime prevent it?

MediumOracle
4

What is the difference between connectionTimeout and maxLifetime in HikariCP?

MediumBooking.com
5

How would you detect and alert on HikariCP pool exhaustion in production?

MediumNetflix

Ask Aria about Connection Pool — HikariCP

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…