1. Welcome Developer Playground by Giri

Developer Playground

Understanding R2DBC Connection Pool

Updated: April 21, 2025

R2DBC vs HikariCP Connection Management

R2DBC connection pooling implements a similar approach to traditional JDBC connection pools like HikariCP, with some notable differences in connection handling philosophy.

  • R2DBC does support minimum idle connections (min idle)
  • R2DBC follows a reactive programming model while maintaining connection availability
  • Connections are maintained according to the configured minimum idle setting
  • This design balances reactive programming principles with practical performance needs

Connection Strategy Comparison:

  • HikariCP: Maintains minimum connections (minimumIdle)
  • R2DBC: Also maintains minimum connections through minIdle configuration
R2DBC vs HikariCP Connection PoolR2DBC Connection PoolHikariCP Connection PoolinitialSize (initial connections)maxSize (maximum connections)minIdle (minimum idle connections)Reactive connection managementmaximumPoolSizeminimumIdleidleTimeoutTraditional JDBC approachReactive philosophy with min idleTraditional JDBC approachBoth R2DBC and HikariCP support maintaining minimum idle connections

io.r2dbc.pool.ConnectionPool Configuration

The ConnectionPool in R2DBC provides several configuration options for managing the lifecycle of database connections, including support for minimum idle connections.

Key configuration parameters:

  • initialSize = 10: Creates 10 connections when the pool is initialized
  • maxSize = 10: Maximum number of connections in the pool is 10
  • minIdle: Sets the minimum number of idle connections to maintain in the pool
  • maxIdleTime = Duration.ofMinutes(30): Connections may be removed after 30 minutes of inactivity
  • maxLifeTime = null: No maximum lifetime set for connections (unlimited)

Implementation example:

ConnectionPoolConfiguration configuration = ConnectionPoolConfiguration.builder(connectionFactory)
    .initialSize(10)
    .maxSize(10)
    .minIdle(5)
    .maxIdleTime(Duration.ofMinutes(30))
    .build();

ConnectionPool pool = new ConnectionPool(configuration);

Implementation details:

// R2DBC implementation code showing minIdle support
int cpuCount = Runtime.getRuntime().availableProcessors();
PoolBuilder<Connection, PoolConfig<Connection>> builder = PoolBuilder.from(allocator)
    .clock(configuration.getClock())
    .metricsRecorder(metricsRecorder)
    .evictionPredicate(evictionPredicate)
    .destroyHandler(Connection::close)
    .sizeBetween(Math.min(configuration.getMinIdle(), cpuCount), cpuCount)
    .idleResourceReuseMruOrder();

if (maxSize != -1 && initialSize <= 0) {
    builder.sizeBetween(Math.max(configuration.getMinIdle(), initialSize), maxSize);
} else {
    builder.sizeBetween(Math.max(configuration.getMinIdle(), initialSize),
                      maxSize == -1 ? Integer.MAX_VALUE : maxSize);
}

Connection Eviction Behavior

Understanding how R2DBC manages connection eviction is important for optimizing pool performance.

Key eviction behaviors:

  • maxIdleTime and maxLifeTime operate independently
  • When maxLifeTime is reached, the connection is terminated regardless of maxIdleTime
  • With maxIdleTime set to 30 minutes, idle connections exceeding this time are removed
  • If either condition (idle time or lifetime) is met, the connection will be evicted
  • Eviction will not reduce the pool below the configured minIdle value
// Create eviction predicate that checks maxIdleTime and maxLifeTime.
// This is because "PoolBuilder#evictionIdle()" and "PoolBuilder#evictionPredicate()" cannot be used together in
// current implementation. (<https://github.com/reactor/reactor-pool/issues/33>)
// To workaround the issue, here defines an evictionPredicate that performs both maxIdleTime and maxLifeTime check.
BiPredicate<Connection, PooledRefMetadata> evictionPredicate = (connection, metadata) -> {
    if (maxIdleTime.isZero() || maxLifeTime.isZero()) {
        // evict immediately
        return true;
    }
    boolean isIdleTimeExceeded = !maxIdleTime.isNegative() && metadata.idleTime() >= maxIdleTime.toMillis();
    boolean isLifeTimeExceeded = !maxLifeTime.isNegative() && metadata.lifeTime() >= maxLifeTime.toMillis();
    return isIdleTimeExceeded || isLifeTimeExceeded;
};

This code demonstrates how R2DBC implements the eviction predicate that determines when connections should be removed from the pool. The eviction occurs if either the idle time or lifetime thresholds are exceeded, while maintaining the minimum idle connections specified.

R2DBC Connection LifecycleConnection Pool (maxSize = 10, minIdle = 5)Active ConnectionsIdle Connections(Maintained by minIdle)Potential Connections(Created on demand)maxIdleTime exceeded(if above minIdle)maxLifeTime exceededCreated when neededConnection Eviction (when idle time or lifetime exceeded, respecting minIdle)NewConnectionRequestMinimum idle connections maintainedR2DBC maintains minimum idle connections while following reactive principles

Reactive Approach and Pool Sizing

R2DBC's connection pool design balances reactive programming principles with practical connection management, providing both efficiency and availability.

Connection Acquisition Strategy:

  • initialSize creates connections at startup
  • minIdle ensures a minimum number of connections are maintained
  • New connections are established as needed up to maxSize
  • This approach provides both resource efficiency and connection availability guarantees

Recommendations for Configuration:

  • Set initialSize based on expected baseline connection needs
  • Configure minIdle to ensure a minimum level of connection availability
  • Set maxSize based on peak connection requirements
  • Tune maxIdleTime to balance resource utilization with connection reuse

Important Note: R2DBC's support for minimum idle connections ensures consistent availability with minimal latency, providing a similar guarantee to what traditional connection pools like HikariCP offer.

Conclusion

R2DBC connection pool combines a reactive design philosophy with practical connection management features similar to traditional JDBC connection pools like HikariCP. Key features include:

  • Support for minimum idle connections through the minIdle setting
  • Connection eviction based on either idle time or total lifetime
  • Resource-efficient approach that aligns with reactive programming principles
  • Provides connection availability guarantees similar to traditional connection pools

This document confirms that R2DBC does support a minimum idle connection feature similar to HikariCP's minimumIdle. While still following reactive programming principles, R2DBC provides the ability to maintain a minimum pool of connections for consistent availability and performance.

Copyright © 2025 Giri Labs Inc.·Trademark Policy