Hikari Connection Pool with Spring Boot made simple

HikariCP is a fast, simple, production ready JDBC connection pool. In this article we will learn how to configure it in Spring Boot applications. Then, we will cover how to monitor Hikari Connection Pool properties using Spring Boot actuator.

Setting up Hikari Connection Pool

Firstly, let’s see how to configure Hikari Connection Pool in Spring Boot. The good news is that Hikari is the default Connection Pool for Spring Boot 2 applications so you don’t need to add any extra dependency to your project.

As a matter of fact, if you try adding com.zaxxer:HikariCP to your project, Eclipse will report that you are overriding the default implementation available in Spring Boot 2 starters:

Hikari connection pool spring boot

Configuring Hikari Pool

To configure Hikari Connection Pool you can use the application.properties file. Here is a sample configuration:

spring.datasource.hikari.connectionTimeout=40000 
spring.datasource.hikari.idleTimeout=600000 
spring.datasource.hikari.maxLifetime=1200000

Here is a list of most common properties you can include:

spring.datasource.hikari.autoCommit: This property controls the default auto-commit behavior of connections returned from the pool. It is a boolean value. Default: true

spring.datasource.hikari.connectionTimeout: This property controls the maximum number of milliseconds that a client will wait for a connection from the pool. If this time exceeds without a connection becoming available, a SQLException will be thrown. Default: 30000 (30 seconds)

spring.datasource.hikari.idleTimeout: This property controls the maximum amount of time that a connection is allowed to sit idle in the pool.. A value of 0 means that idle connections are never removed from the pool. The minimum allowed value is 10000ms (10 seconds). Default: 600000 (10 minutes)

spring.datasource.hikari.keepaliveTime: This property controls how frequently HikariCP will attempt to keep a connection alive, in order to prevent it from being timed out by the database or network infrastructure. This value must be less than the maxLifetime value. A “keepalive” will only occur on an idle connection. The minimum allowed value is 30000ms (30 seconds), but a value in the range of minutes is most desirable. Default: 0 (disabled)

spring.datasource.hikari.maxLifetime: This property controls the maximum lifetime of a connection in the pool. An in-use connection will never be retired, only when it is closed will it then be removed. The minimum allowed value is 30000ms (30 seconds). Default: 1800000 (30 minutes)

spring.datasource.hikari.minimumIdle: This property controls the minimum number of idle connections that HikariCP tries to maintain in the pool. If the idle connections dip below this value and total connections in the pool are less than maximumPoolSize, HikariCP will make a best effort to add additional connections quickly and efficiently. Default: same as maximumPoolSize

spring.datasource.hikari.maximumPoolSize: This property controls the maximum size that the pool is allowed to reach, including both idle and in-use connections. Basically this value will determine the maximum number of actual connections to the database backend. Default: 10

spring.datasource.hikari.poolName: This property represents a user-defined name for the connection pool and appears mainly in logging and JMX management consoles to identify pools and pool configurations. Default: auto-generated.

Configuring Hikari Pool for Spring Boot 1 applications

If you are still running Spring Boot 1 applications, you have to exclude the default  tomcat JDBC connection pool and add HikariCP Pool. Example:

<dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>3.3.1</version>
    </dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Hikari Connection Pool in action

The following application shows a sample JPA application using Hikari Pool: https://github.com/fmarchioni/masterspringboot/tree/master/jpa/hikari-pool

When you start the application, you will see from the logs that the Hikari Pool has started:

2021-11-13 09:36:32.787  INFO 5648 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-11-13 09:36:32.863  INFO 5648 --- [  restartedMain] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:aad5aac5-de80-4f64-85c0-b42a4a2e434f user=SA
2021-11-13 09:36:32.873  INFO 5648 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.

Monitoring Hikari Connection Pool

You can monitor the Datasource properties by simply enabling the actuator metrics in your application.properties:

management.endpoint.metrics.enabled = true
management.endpoints.web.exposure.include = metrics

You can check the available metrics with:

curl -s http://localhost:8080/actuator/metrics | jq
{
  "names": [
    "hikaricp.connections",
    "hikaricp.connections.acquire",
    "hikaricp.connections.active",
    "hikaricp.connections.creation",
    "hikaricp.connections.idle",
    "hikaricp.connections.max",
    "hikaricp.connections.min",
    "hikaricp.connections.pending",
    "hikaricp.connections.timeout",
    "hikaricp.connections.usage",
    "http.server.requests",
    "jdbc.connections.active",
    "jdbc.connections.idle",
    "jdbc.connections.max",
    "jdbc.connections.min",
    "spring.data.repository.invocations",
    "tomcat.sessions.active.current",
    "tomcat.sessions.active.max",
    "tomcat.sessions.alive.max",
    "tomcat.sessions.created",
    "tomcat.sessions.expired",
    "tomcat.sessions.rejected"
  ]
}

So, for example, if you want to check a single metric value, such as the hikaricp.connections.active, you can run:

curl -s http://localhost:8080/actuator/metrics/hikaricp.connections.active | jq
{
  "name": "hikaricp.connections.active",
  "description": "Active connections",
  "baseUnit": null,
  "measurements": [
    {
      "statistic": "VALUE",
      "value": 4
    }
  ],
  "availableTags": [
    {
      "tag": "pool",
      "values": [
        "HikariPool-1"
      ]
    }
  ]
}

Hikari Connection Pool Caveats When Database is Unavailable

One of the common problems that HikariCP users may face is when the database becomes unavailable. HikariCP tries to check before offering the connection from the pool by running a sample query. If the connection fails, HikariCP discards it and removes it from the pool. This process avoids giving a connection that has already gone stale or is no longer valid.

HikariCP’s ability to refill the pool after removing a dead connection seems like a blessing, but it has its downside. The pool continuously tries to create new connections asynchronously until the timeout we set in HikariCP’s configuration is over. This means that if the database is still down, our application will keep trying to create new connections until the timeout expires.

Moreover, if all connections from the pool are busy, and a new request comes in, HikariCP creates a new connection and adds it to its concurrent connection bag. This ensures that the thread safety of the operation is maintained since offering a connection to multiple requests simultaneously can cause issues.

However, when the pool is exhausted, and HikariCP tries to create a new connection asynchronously, there is a possibility that the connection attempt would fail if the database is still not up, causing connection exceptions.

[PostgreSQL]:connection attempt failed…

[PostgreSQL]:connection attempt failed…

It is essential to note that connection timeout is a contract between the application and the pool. If the application cannot obtain a connection within the specified time, it gets an exception. HikariCP handles the connection not available exceptions in a thread-safe manner.

In conclusion, HikariCP is an excellent connection pool that can optimize the performance of our applications by providing fast, efficient, and reliable connections. However, we must consider the caveats and handle them gracefully. When the database is unavailable, HikariCP continuously tries to create new connections asynchronously, which may cause connection timeout exceptions. By understanding these limitations, we can write better code and ensure the optimal performance of our applications.

Found the article helpful? if so please follow us on Socials
Twitter Icon       Facebook Icon       LinkedIn Icon       Mastodon Icon