Backend Development 14 min read

Why HikariCP Is So Fast: An In‑Depth Source Code Exploration

This article examines the design and implementation details of HikariCP—Spring Boot's default JDBC connection pool—explaining how its dual‑pool architecture, FastList collection, custom ConcurrentBag, bytecode‑level optimizations, and efficient connection acquisition and release mechanisms together deliver exceptional performance for Java backend applications.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Why HikariCP Is So Fast: An In‑Depth Source Code Exploration

Spring Boot 2.0 adopted HikariCP as its default JDBC connection pool, bringing a lightweight ( ~130KB ) and high‑performance solution originally created by a Japanese developer. The article first introduces the concept of connection pools as a buffering technique that enables connection reuse, then dives into HikariCP’s specific design.

Key reasons for HikariCP’s speed are enumerated:

Two HikariPool instances: a final fast‑path pool and a volatile regular pool, avoiding lazy initialization and volatile overhead.

Replacement of ArrayList with a custom FastList that omits range‑check logic and removes elements from the tail, matching the typical open‑close order of connections.

A custom lock‑free concurrent collection ConcurrentBag that stores PoolEntry objects, providing faster concurrent access.

Thread‑local caching of connections, allowing the same thread to obtain a connection without synchronization.

Bytecode reduction via Javassist‑generated proxies, resulting in fewer bytes than standard JDK dynamic proxies.

The article then shows a minimal Maven dependency for HikariCP and a JUnit test that configures a HikariConfig , creates a HikariDataSource , obtains a connection, executes a simple query, and finally closes all resources:

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

@Test
public void testHikariCP() throws SQLException {
    HikariConfig hikariConfig = new HikariConfig();
    hikariConfig.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/iam?characterEncoding=utf8");
    hikariConfig.setUsername("root");
    hikariConfig.setPassword("123456");
    hikariConfig.setPoolName("testHikari");
    hikariConfig.setMinimumIdle(4);
    hikariConfig.setMaximumPoolSize(8);
    hikariConfig.setIdleTimeout(600000L);
    hikariConfig.setConnectionTimeout(10000L);

    HikariDataSource dataSource = new HikariDataSource(hikariConfig);
    Connection connection = dataSource.getConnection();
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) AS countNum tt_user");
    if (resultSet.next()) {
        System.out.println("countNum结果为:" + resultSet.getInt("countNum"));
    }
    resultSet.close();
    statement.close();
    connection.close();
    dataSource.close();
}

The HikariDataSource implements the standard DataSource interface and offers two constructors: a no‑arg constructor (leaving fastPathPool null) and a constructor that accepts a HikariConfig , initializing both fastPathPool and pool immediately for better performance.

Key parts of the HikariPool implementation are highlighted, such as the private fields:

private final HikariPool fastPathPool;
private volatile HikariPool pool;

The pool creation logic sets up a ConcurrentBag for connection tracking, a SuspendResumeLock for optional pool suspension, a bounded LinkedBlockingQueue for connection‑adder tasks, and a ThreadPoolExecutor for connection‑closer tasks. A scheduled HouseKeeper task periodically calls fillPool() to maintain the desired pool size.

The fillPool() method calculates how many connections to add and submits creation tasks to the addConnectionExecutor . The PoolEntryCreator implements Callable<Boolean> and repeatedly creates PoolEntry objects, adding them to the ConcurrentBag via connectionBag.add(poolEntry) .

When a client calls getConnection() , the fast‑path pool is tried first; if null, the regular pool is lazily initialized using double‑checked locking. The actual acquisition uses connectionBag.borrow(timeout, MILLISECONDS) , which first checks a thread‑local list, then the shared CopyOnWriteArrayList , and finally a SynchronousQueue for waiting threads.

Releasing a connection involves the close() method of the proxy connection, which closes any open Statement s stored in a FastList , then calls poolEntry.recycle(lastAccess) . The recycle logic returns the connection to the thread‑local cache (up to 50 entries) or offers it to the waiting queue, ensuring fast hand‑off to other threads.

In summary, the article demonstrates that HikariCP’s performance stems from many small, carefully engineered details—dual pools, lock‑free collections, thread‑local caching, and bytecode‑level optimizations—all of which accumulate to make it a highly efficient JDBC connection pool for backend Java services.

BackendJavaPerformanceConcurrencyConnection PoolHikariCP
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.