HikariCP

repository·dev·Indexed 12 days ago

https://github.com/brettwooldridge/hikaricp

A high-performance, minimalist JDBC connection pool for Java applications. Includes documentation on configuration properties such as maximumPoolSize and maxLifetime, initialization via HikariConfig and HikariDataSource, and support for Java versions 6 through 11+ (version 7.1.0).

Tokens
6.3K
Snippets
12
Records
20
Agent score
98%

What's inside HikariCP

  1. Best practices for handling spike demand

    dev

    When your application experiences sudden spikes in request volume, the configuration of your connection pool significantly impacts performance and database resource consumption.

    For the best performance in response to spike demands, HikariCP recommends using a fixed-size pool. A fixed-size pool avoids the latency penalty of establishing new connections during a spike.

    The Risk of Dynamic Sizing

    Using a dynamically-sized pool (e.g., setting minimumIdle to a value lower than maximumPoolSize) in an environment where connection establishment is expensive (e.g., due to DNS, encryption, or external authentication) can lead to:

    1. Increased Latency: New requests must wait for the connection establishment time (which can be hundreds of milliseconds).
    2. Connection Bloat: Other connection pools may aggressively create many new connections to satisfy a spike, whereas HikariCP uses elision logic to ensure that if a spike is transient, it only adds the minimum necessary connections to satisfy demand, preventing unnecessary resource consumption on the database server.
  2. Concept: Statement Caching and Logging

    dev

    Statement Caching

    HikariCP does not provide PreparedStatement caching at the pool layer. This is a deliberate design choice to avoid the anti-pattern of caching statements per connection, which leads to excessive memory usage and redundant execution plans in the database.

    Instead, you should use the statement cache provided by your database's JDBC driver (e.g., PostgreSQL, Oracle, MySQL, etc.). Driver-level caches are more efficient as they can share execution plans across connections.

    Log Statement Text / Slow Query Logging

    Similar to statement caching, HikariCP defers statement logging to the database driver. Most major vendors (Oracle, MySQL, Derby, MSSQL) support this natively. If your driver does not support it, consider using third-party tools like p6spy, log4jdbc, or jdbcdslog-exp.

  3. Configure TCP Keepalive to prevent pool exhaustion

    dev

    To avoid a rare condition where the connection pool drops to zero and fails to recover, you must configure TCP keepalive.

    Some JDBC drivers allow this via properties (e.g., tcpKeepAlive=true for PostgreSQL). Alternatively, it can be configured at the Operating System level. Proper TCP keepalive settings ensure that connections are not silently dropped by network infrastructure.

  4. Requirements for HikariCP

    dev

    To use the current version of HikariCP, ensure your environment meets the following requirements:

    • Java: Java 11 or higher. (Note: Artifacts for Java 6, 7, and 8 are in maintenance mode).
    • Logging: The slf4j library must be present in your classpath.
  5. Initialize HikariCP from java.util.Properties

    dev

    You can pass a java.util.Properties object to the HikariConfig constructor.

    Properties props = new Properties();
    props.setProperty("dataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
    props.setProperty("dataSource.user", "test");
    props.setProperty("dataSource.password", "test");
    props.setProperty("dataSource.databaseName", "mydb");
    props.put("dataSource.logWriter", new PrintWriter(System.out));
    
    HikariConfig config = new HikariConfig(props);
    HikariDataSource ds = new HikariDataSource(config);
  6. Run the spike demand simulation benchmark

    dev

    The project includes a simulation harness to test how different connection pools handle sudden spikes in demand. You can run the spiketest.sh script to compare HikariCP against other pools like dbcp2, vibur, tomcat, or c3p0.

    Command Syntax:

    ./spiketest.sh <connection_establishment_time_ms> <pool_name> <number_of_threads>

    Arguments:

    • <connection_establishment_time_ms>: The time (in milliseconds) it takes to establish a new connection.
    • <pool_name>: The name of the pool to test. Supported values: hikari, dbcp2, vibur, tomcat, c3p0.
    • <number_of_threads>: The number of concurrent threads/requests hitting the pool at once.
    ./spiketest.sh 150 <pool> 50
  7. Initialize HikariCP via HikariDataSource

    dev

    For simple setups, you can instantiate HikariDataSource directly and use its setter methods.

    HikariDataSource ds = new HikariDataSource();
    ds.setJdbcUrl("jdbc:mysql://localhost:3306/simpsons");
    ds.setUsername("bart");
    // ...
  8. Install HikariCP via Maven

    dev

    Depending on your Java version, select the appropriate Maven dependency. For modern projects, use the Java 11+ artifact. Older versions are available but are considered deprecated.

    ### Java 11+ (Recommended)
    ```xml
    <dependency>
       <groupId>com.zaxxer</groupId>
       <artifactId>HikariCP</artifactId>
       <version>7.1.0</version>
    </dependency>

    Java 8 (Deprecated)

    <dependency>
       <groupId>com.zaxxer</groupId>
       <artifactId>HikariCP</artifactId>
       <version>4.0.3</version>
    </dependency>

    Java 7 (Deprecated)

    <dependency>
       <groupId>com.zaxxer</groupId>
       <artifactId>HikariCP-java7</artifactId>
       <version>2.4.13</version>
    </dependency>

    Java 6 (Deprecated)

    <dependency>
       <groupId>com.zaxxer</groupId>
       <artifactId>HikariCP-java6</artifactId>
       <version>2.3.13</version>
    </dependency>
  9. Initialize HikariCP from a properties file

    dev

    HikariCP can be configured using a .properties file located on the filesystem or the classpath. You can pass the path to the HikariConfig constructor.

    Alternatively, you can set the Java system property hikaricp.configurationFile to specify the location of the properties file. If this system property is used, you should construct HikariConfig or HikariDataSource using the default constructor.

    // Examines both filesystem and classpath for .properties file
    HikariConfig config = new HikariConfig("/some/path/hikari.properties");
    HikariDataSource ds = new HikariDataSource(config);

    Example properties file content:

    dataSourceClassName=org.postgresql.ds.PGSimpleDataSource
    dataSource.user=test
    dataSource.password=test
    dataSource.databaseName=mydb
    dataSource.portNumber=5432
    dataSource.serverName=localhost
  10. Initialize HikariCP via HikariConfig

    dev

    You can initialize the connection pool using the HikariConfig class. This is the preferred method for programmatic setup.

    Note: The following example uses MySQL-specific properties and should not be copied verbatim for other databases.

    HikariConfig config = new HikariConfig();
    config.setJdbcUrl("jdbc:mysql://localhost:3306/simpsons");
    config.setUsername("bart");
    config.setPassword("51mp50n");
    config.addDataSourceProperty("cachePrepStmts", "true");
    config.addDataSourceProperty("prepStmtCacheSize", "250");
    config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
    
    HikariDataSource ds = new HikariDataSource(config);
  11. Configure advanced HikariCP properties

    dev

    These properties are used for specialized tuning, monitoring, or specific environment requirements.

    Monitoring & Health

    • metricRegistry: (Programmatic only) Specify a Codahale/Dropwizard MetricRegistry to record pool metrics.
    • healthCheckRegistry: (Programmatic only) Specify a Codahale/Dropwizard HealthCheckRegistry to report pool health.
    • registerMbeans: Controls whether JMX Management Beans ("MBeans") are registered. Default is false.
    • leakDetectionThreshold: The amount of time a connection can be out of the pool before a message is logged indicating a possible leak. A value of 0 disables detection. Minimum value is 2000 (2 seconds). Default is 0.

    Connection Initialization & Behavior

    • connectionInitSql: A SQL statement executed after every new connection creation before it is added to the pool.
    • initializationFailTimeout: Controls whether the pool "fails fast" if it cannot be seeded with an initial connection.
      • Positive value: Milliseconds to attempt to acquire an initial connection.
      • 0: Attempt to obtain/validate a connection; if it fails validation, the pool won't start. If it fails to be obtained, the pool starts but later attempts may fail.
      • Negative value: Bypasses initial connection attempt; pool starts immediately and attempts to obtain connections in the background. Default is 1.
    • driverClassName: The name of the JDBC driver class. Omit this unless you receive an error indicating the driver was not found. Default is none.
    • transactionIsolation: The default transaction isolation level (e.g., TRANSACTION_READ_COMMITTED). Uses constant names from the Connection class. Default is the driver default.
    • readOnly: Whether connections are in read-only mode by default. Default is false.
    • isolateInternalQueries: Determines if internal pool queries (like aliveness tests) are isolated in their own transaction. Only applies if autoCommit is disabled. Default is false.
    • allowPoolSuspension: Controls whether the pool can be suspended/resumed via JMX. When suspended, getConnection() calls will block until resumed rather than timing out. Default is false.

    Database Metadata

    • catalog: Sets the default catalog for databases that support it. Default is the driver default.
    • schema: Sets the default schema for databases that support it. Default is the driver default.

    Programmatic Configuration

    • dataSource: (Programmatic only) Directly set the DataSource instance to be wrapped, bypassing reflection-based construction. When used, dataSourceClassName and other DataSource-specific properties are ignored.
    • threadFactory: (Programmatic only) Set a java.util.concurrent.ThreadFactory for creating pool threads. Useful in restricted execution environments. Default is none.
  12. Configure frequently used HikariCP properties

    dev

    The following properties are commonly used to tune the connection pool's behavior. Most time-based values are in milliseconds.

    Connection Lifecycle & Sizing

    • maximumPoolSize: The maximum number of connections (both idle and in-use) allowed in the pool. Default is 10.
    • minimumIdle: The minimum number of idle connections HikariCP tries to maintain. For maximum performance, it is recommended to not set this, allowing the pool to act as a fixed-size pool (where minimumIdle equals maximumPoolSize). Default is the same as maximumPoolSize.
    • idleTimeout: The maximum time a connection can sit idle in the pool. Only applies when minimumIdle is less than maximumPoolSize. A value of 0 means idle connections are never removed. Minimum value is 10000 (10 seconds). Default is 600000 (10 minutes).
    • maxLifetime: The maximum lifetime of a connection in the pool. We strongly recommend setting this to several seconds shorter than any database or infrastructure-imposed connection time limit. A value of 0 indicates infinite lifetime. Minimum value is 30000 (30 seconds). Default is 1800000 (30 minutes).
    • keepaliveTime: How frequently HikariCP attempts to keep a connection alive (by pinging it) to prevent timeouts from the database or network. Must be less than maxLifetime. Minimum value is 30000 (30 seconds). Default is 120000 (2 minutes).

    Connection Acquisition & Validation

    • connectionTimeout: The maximum time a client will wait for a connection from the pool before a SQLException is thrown. Lowest acceptable value is 250 ms. Default is 30000 (30 seconds).
    • connectionTestQuery: The query executed to validate a connection is alive. If your driver supports JDBC4, do not set this property; HikariCP will use the JDBC4 Connection.isValid() API instead.
    • validationTimeout: The maximum time a connection will be tested for aliveness. Must be less than connectionTimeout. Lowest acceptable value is 250 ms. Default is 5000 ms.

    Authentication & Defaults

    • password: The default authentication password used when obtaining connections. For DataSource-based configurations, this calls DataSource.getConnection(username, password). For Driver-based configurations, it is added to the Properties passed to DriverManager.getConnection(jdbcUrl, props). If you need a different property name, use addDataSourceProperty("name", value) instead.
    • autoCommit: Controls the default auto-commit behavior of connections. Default is true.