Introduction
HikariCP is the default connection pool in Spring Boot. To enable HikariCP logging, set the com.zaxxer.hikari logger to DEBUG in your application.properties or application.yml. This exposes connection acquisition times, pool statistics (active, idle, waiting connections), leak detection warnings, and connection lifecycle events. Monitoring these logs is essential for diagnosing slow database queries, connection leaks, and pool exhaustion issues.
Basic Logging Configuration
application.properties
1# Enable HikariCP debug logging
2logging.level.com.zaxxer.hikari=DEBUG
3logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
4
5# For detailed pool statistics
6logging.level.com.zaxxer.hikari.pool.HikariPool=DEBUG
application.yml
1logging:
2 level:
3 com.zaxxer.hikari: DEBUG
4 com.zaxxer.hikari.HikariConfig: DEBUG
5 com.zaxxer.hikari.pool.HikariPool: DEBUG
What the Logs Show
At DEBUG level, HikariCP logs:
DEBUG HikariPool - HikariPool-1 - Pool stats (total=10, active=3, idle=7, waiting=0)
DEBUG HikariPool - HikariPool-1 - Added connection conn5
DEBUG HikariPool - HikariPool-1 - Timeout failure stats (total=10, active=10, idle=0, waiting=5)
| Log Entry | Meaning |
total=10 | Total connections in the pool |
active=3 | Connections currently in use |
idle=7 | Connections available for use |
waiting=0 | Threads waiting for a connection |
Added connection | New connection was created |
Timeout failure | Thread could not get a connection in time |
Pool Configuration
1# application.properties
2spring.datasource.hikari.maximum-pool-size=20
3spring.datasource.hikari.minimum-idle=5
4spring.datasource.hikari.connection-timeout=30000
5spring.datasource.hikari.idle-timeout=600000
6spring.datasource.hikari.max-lifetime=1800000
7spring.datasource.hikari.pool-name=MyAppPool
1# application.yml
2spring:
3 datasource:
4 hikari:
5 maximum-pool-size: 20
6 minimum-idle: 5
7 connection-timeout: 30000 # 30 seconds
8 idle-timeout: 600000 # 10 minutes
9 max-lifetime: 1800000 # 30 minutes
10 pool-name: MyAppPool
Setting pool-name makes logs easier to identify when multiple pools exist.
Leak Detection
HikariCP can detect connections that are borrowed but not returned:
# Warn if a connection is held for more than 30 seconds
spring.datasource.hikari.leak-detection-threshold=30000
1spring:
2 datasource:
3 hikari:
4 leak-detection-threshold: 30000 # 30 seconds
When a leak is detected, HikariCP logs a stack trace showing where the connection was acquired:
1WARN HikariPool - Connection leak detection triggered for conn7 on thread http-nio-8080-exec-3,
2stack trace follows
3java.lang.Exception: Apparent connection leak detected
4 at com.example.UserRepository.findAll(UserRepository.java:25)
5 at com.example.UserService.getUsers(UserService.java:18)
6 ...
This stack trace shows exactly which code acquired the connection but did not return it.
Monitoring with JMX
Enable JMX to expose pool metrics programmatically:
spring.datasource.hikari.register-mbeans=true
1// Access pool metrics programmatically
2import com.zaxxer.hikari.HikariDataSource;
3import com.zaxxer.hikari.HikariPoolMXBean;
4
5@RestController
6public class PoolMonitorController {
7
8 private final HikariDataSource dataSource;
9
10 public PoolMonitorController(DataSource dataSource) {
11 this.dataSource = (HikariDataSource) dataSource;
12 }
13
14 @GetMapping("/pool-stats")
15 public Map<String, Integer> getPoolStats() {
16 HikariPoolMXBean pool = dataSource.getHikariPoolMXBean();
17 return Map.of(
18 "activeConnections", pool.getActiveConnections(),
19 "idleConnections", pool.getIdleConnections(),
20 "totalConnections", pool.getTotalConnections(),
21 "threadsAwaitingConnection", pool.getThreadsAwaitingConnection()
22 );
23 }
24}
Spring Boot Actuator Integration
1<dependency>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-actuator</artifactId>
4</dependency>
management.endpoints.web.exposure.include=health,metrics
management.endpoint.health.show-details=always
Access pool metrics at:
1# Health check includes pool status
2curl http://localhost:8080/actuator/health
3
4# HikariCP-specific metrics
5curl http://localhost:8080/actuator/metrics/hikaricp.connections.active
6curl http://localhost:8080/actuator/metrics/hikaricp.connections.idle
7curl http://localhost:8080/actuator/metrics/hikaricp.connections.pending
8curl http://localhost:8080/actuator/metrics/hikaricp.connections.timeout
9curl http://localhost:8080/actuator/metrics/hikaricp.connections.usage
Micrometer/Prometheus Integration
# Expose Prometheus endpoint
management.endpoints.web.exposure.include=prometheus
1# Grafana queries for HikariCP monitoring
2hikaricp_connections_active{pool="MyAppPool"}
3hikaricp_connections_idle{pool="MyAppPool"}
4hikaricp_connections_pending{pool="MyAppPool"}
5rate(hikaricp_connections_timeout_total{pool="MyAppPool"}[5m])
6hikaricp_connections_usage_seconds_sum / hikaricp_connections_usage_seconds_count
Logging SQL Queries Alongside Pool Logs
1# Log SQL statements
2logging.level.org.springframework.jdbc.core=DEBUG
3logging.level.org.hibernate.SQL=DEBUG
4
5# Log SQL parameter values
6logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
7
8# Combined with HikariCP logs
9logging.level.com.zaxxer.hikari=DEBUG
Common Pitfalls
Setting pool size too high: More connections is not always better. Each connection consumes memory on both the application and database. Start with maximum-pool-size = (2 * CPU cores) + number_of_disks and tune based on load testing.
Not enabling leak detection in development: Without leak-detection-threshold, connections held indefinitely (e.g., from missing @Transactional or unclosed resources) silently exhaust the pool. Set it to 30-60 seconds in development.
Confusing connection timeout with query timeout: connection-timeout is how long to wait for a connection from the pool. Query timeout (how long a SQL query can run) is configured separately via spring.jpa.properties.jakarta.persistence.query.timeout.
Logging at TRACE level in production: HikariCP TRACE logging is extremely verbose and impacts performance. Use DEBUG for troubleshooting and INFO for production.
Not monitoring threadsAwaitingConnection: A non-zero waiting count means the pool is undersized or connections are held too long. This is the earliest indicator of pool exhaustion, appearing before timeout errors.
Summary
Set logging.level.com.zaxxer.hikari=DEBUG to enable HikariCP connection pool logging
Enable leak detection with spring.datasource.hikari.leak-detection-threshold=30000 to find unreturned connections
Use Spring Boot Actuator metrics (hikaricp.connections.*) for runtime monitoring
Key metrics to watch: active connections, idle connections, threads awaiting connection, and timeout count
Set pool-name for clear log identification, especially with multiple data sources