Master HikariCP connection pooling. Learn sizing formulas, configuration tuning, and how to avoid connection starvation.
JOptimize Team
Database connections are expensive. Creating a connection takes 100-500ms. Opening N connections per request destroys throughput.
Connection pooling maintains a pre-allocated set of ready connections. Request a connection, use it, return it. Reuse, don't recreate.
HikariCP is the best pool. This guide covers HikariCP configuration, sizing, common mistakes, and production tuning.
// Bad: New connection per request public void processRequest() { Connection conn = DriverManager.getConnection(url, user, pass); // 100-500ms! try { stmt.executeQuery(); } finally { conn.close(); } } // 100 concurrent requests × 200ms = 20s total wait
Without pooling, latency explodes. With pooling, connections are ready.
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>5.1.0</version> </dependency>
# application.properties spring.datasource.hikari.maximum-pool-size=20 spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.connection-timeout=10000 spring.datasource.hikari.idle-timeout=600000 spring.datasource.hikari.max-lifetime=1800000
Optimal pool size depends on CPU cores and I/O:
pool_size = (core_count × 2) + spindle_count
For an 8-core machine with 1 disk:
pool_size = (8 × 2) + 1 = 17
4-core CPU: (4 × 2) + 1 = 9 connections 8-core CPU: (8 × 2) + 1 = 17 connections 16-core CPU: (16 × 2) + 1 = 33 connections
Maximum connections. Use the formula above.
spring.datasource.hikari.maximum-pool-size=17
Minimum idle connections ready. Typically half of maximum.
spring.datasource.hikari.minimum-idle=8
HikariCP keeps at least 8 connections open, ready to use.
How long to wait if no connection available. Default 30s (too long).
spring.datasource.hikari.connection-timeout=10000 # 10 seconds
If no connection after 10s, throw exception. Fail fast.
How long before idle connections are closed. Default 10 minutes.
spring.datasource.hikari.idle-timeout=600000 # 10 minutes
Connections used less frequently close after 10m idle.
Maximum connection age. Default 30 minutes. Set lower than database timeout.
spring.datasource.hikari.max-lifetime=1800000 # 30 minutes
Some databases kill connections after 60m. Set max-lifetime to 50m to stay safe.
# High-throughput application spring.datasource.hikari.maximum-pool-size=25 spring.datasource.hikari.minimum-idle=10 spring.datasource.hikari.connection-timeout=5000 spring.datasource.hikari.idle-timeout=600000 spring.datasource.hikari.max-lifetime=1800000 spring.datasource.hikari.leak-detection-threshold=60000
Alert if connection held >60s (likely forgotten return).
spring.datasource.hikari.leak-detection-threshold=60000 # 60 seconds
# Bad: Only 3 connections for 8 cores spring.datasource.hikari.maximum-pool-size=3
Requests queue up. Latency spikes.
# Bad: 100 connections for 8 cores spring.datasource.hikari.maximum-pool-size=100
Wasted memory. Database connection limits exhausted. Other apps can't connect.
// Bad: Connection never returned Connection conn = dataSource.getConnection(); if (someError) { throw new Exception(); // conn leak }
Use try-with-resources:
// Good: Auto-closes try (Connection conn = dataSource.getConnection()) { stmt.executeQuery(); }
// Bad: Hold connection for long processing try (Connection conn = dataSource.getConnection()) { conn.setAutoCommit(false); // 10 seconds of business logic expensiveCalculation(); // Expensive network call externalApi.call(); conn.commit(); // Finally release }
Hold connections only for DB operations.
// Micrometer metrics @Autowired HikariDataSource dataSource; public void checkPoolHealth() { int active = dataSource.getHikariPoolMXBean().getActiveConnections(); int idle = dataSource.getHikariPoolMXBean().getIdleConnections(); int pending = dataSource.getHikariPoolMXBean().getThreadsAwaitingConnection(); System.out.println("Active: " + active + ", Idle: " + idle + ", Pending: " + pending); }
Alert if:
Connection pooling is essential. HikariCP is the best pool.
Sizing: (cores × 2) + 1. Configuration: timeout 10s, idle 10m, max-lifetime 30m.
Common mistakes: too small, too large, leaks, long transactions.
Monitor pool health - pending connections indicate problems.
Connection pooling is one piece. N+1 queries, missing indexes, unbounded result sets also destroy latency.
JOptimize detects DB hotspots and pool exhaustion:
Use code LINKEDIN40 for 40% OFF JOptimize PRO.
Pool connections. Monitor pool health. Achieve predictable database latency.
Master Spring Boot, security, and Java performance with hands-on courses.
JOptimize finds N+1 queries, EAGER collections, and 70+ other issues in your Java codebase — in under 30 seconds.