PrepZone Logo
PrepZone

Connection Pooling in Production

HikariCP settings, pool sizing math and monitoring active connections.

Why this matters

  • Connection pool exhaustion is a top production failure mode — every request waiting for a connection times out simultaneously.
  • Pool sizing directly affects throughput and database load — too few connections starve requests, too many overwhelm the database.
  • HikariCP is the fastest pool available for Java; Boot configures it automatically when a DataSource starter is present.
Transaction proxy
BEGIN transaction
bookService.placeOrder()Your code
COMMIT or ROLLBACK
Spring wraps your service in a proxy that opens/commits/rolls back the transaction around your method.

Default configuration

Boot auto-configures HikariCP with sensible defaults:

Java
spring:
  datasource:
    url: jdbc:postgresql://127.0.0.1:5432/bookstore
    username: bookstore
    password: ${DB_PASSWORD}
    hikari:
      maximum-pool-size: 10
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      pool-name: BookStorePool

No extra dependency needed — spring-boot-starter-data-jpa includes HikariCP.

Key HikariCP settings

  • maximum-pool-size — Maximum concurrent connections. Default 10.
  • minimum-idle — Connections kept warm when idle. Default equals max pool size.
  • connection-timeout — Milliseconds to wait for a connection before throwing exception. Default 30s.
  • idle-timeout — How long an idle connection stays in the pool. Default 10 minutes.
  • max-lifetime — Maximum age of a connection before retirement. Default 30 minutes.

Pool sizing formula

A widely used guideline:

Java
connections = (core_count * 2) + effective_spindle_count

For a BookStore API on a 4-core server with SSD:

Java
connections = (4 * 2) + 1 = 9

Set maximum-pool-size: 10. Adjust based on monitoring, not theory.

Critical rule: Total connections across all app instances must not exceed the database's max_connections. With 3 BookStore pods at 10 connections each, you need at least 30 available on PostgreSQL.

Monitoring pool health

Enable HikariCP metrics via Actuator:

Java
management:
  endpoints:
    web:
      exposure:
        include: health,metrics
  metrics:
    enable:
      hikaricp: true

Key metrics:

MetricHealthyProblem
hikaricp.connections.activeBelow maxAt max = pool exhausted
hikaricp.connections.pending0> 0 = requests waiting
hikaricp.connections.timeout0> 0 = timeouts occurring
hikaricp.connections.creationStableSpiking = connection churn
  • hikaricp.connections.active

    HealthyBelow max
    ProblemAt max = pool exhausted
  • hikaricp.connections.pending

    Healthy0
    Problem> 0 = requests waiting
  • hikaricp.connections.timeout

    Healthy0
    Problem> 0 = timeouts occurring
  • hikaricp.connections.creation

    HealthyStable
    ProblemSpiking = connection churn

Connection leak detection

Java
spring:
  datasource:
    hikari:
      leak-detection-threshold: 60000

Logs a warning if a connection is held longer than 60 seconds — usually means a transaction was not closed or a connection was not returned to the pool.

Tuning for BookStore workloads

Read-heavy catalog API:

Java
spring:
  datasource:
    hikari:
      maximum-pool-size: 15
      minimum-idle: 5
      connection-timeout: 5000

Write-heavy order processing:

Java
spring:
  datasource:
    hikari:
      maximum-pool-size: 8
      connection-timeout: 10000

Fewer connections for write workloads because transactions hold connections longer.

Read replicas

Route read-only queries to a replica:

Java
@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties("spring.datasource.writer")
    public DataSource writerDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.reader")
    public DataSource readerDataSource() {
        return DataSourceBuilder.create().build();
    }
}

Each pool needs its own sizing — reader pool can be larger since reads are faster.

Validating connections

Java
spring:
  datasource:
    hikari:
      connection-test-query: SELECT 1
      validation-timeout: 3000

HikariCP validates connections before handing them out. The default connection-test-query works for PostgreSQL; H2 and MySQL may need explicit configuration.

Quick recall

Everything you need if you only revisit this box.

  • HikariCP is the default connection pool in Spring Boot — no extra dependency required.
  • maximum-pool-size controls concurrent connections; default is 10.
  • Size pools with (cores * 2) + 1 and adjust based on Actuator metrics.
  • Total connections across all instances must stay below the database limit.
  • leak-detection-threshold warns when connections are held too long.
  • Monitor connections.pending — non-zero means requests are waiting for connections.

Test yourself

Answer these before moving on — recall is what makes it stick.