High-performance JDBC connection pool library for Java applications
—
Pluggable metrics system supporting Micrometer, Dropwizard/Codahale, and Prometheus monitoring frameworks.
Base interfaces for implementing custom metrics tracking.
/**
* Factory interface for creating metrics trackers
*/
public interface MetricsTrackerFactory {
/**
* Create a metrics tracker instance for a specific pool
* @param poolName Name of the connection pool
* @param poolStats PoolStats instance for accessing pool metrics
* @return IMetricsTracker implementation
*/
IMetricsTracker create(String poolName, PoolStats poolStats);
}
/**
* Interface for tracking pool metrics
* All methods have default empty implementations for optional tracking
*/
public interface IMetricsTracker extends AutoCloseable {
/**
* Record time taken to create a new connection
* @param connectionCreatedMillis Time in milliseconds
*/
default void recordConnectionCreatedMillis(long connectionCreatedMillis) {}
/**
* Record time taken to acquire connection from pool
* @param elapsedAcquiredNanos Time in nanoseconds
*/
default void recordConnectionAcquiredNanos(long elapsedAcquiredNanos) {}
/**
* Record time connection was borrowed from pool
* @param elapsedBorrowedMillis Time in milliseconds
*/
default void recordConnectionUsageMillis(long elapsedBorrowedMillis) {}
/**
* Record connection timeout event
*/
default void recordConnectionTimeout() {}
/**
* Close and cleanup metrics resources
*/
@Override
default void close() {}
}
/**
* Abstract base class providing pool statistics
*/
public abstract class PoolStats {
/**
* Constructor with cache timeout
* @param timeoutMs Cache timeout in milliseconds
*/
public PoolStats(long timeoutMs);
// Pool statistics (cached for performance)
public int getTotalConnections();
public int getIdleConnections();
public int getActiveConnections();
public int getPendingThreads();
public int getMaxConnections();
public int getMinConnections();
/**
* Update statistics - implemented by concrete classes
*/
protected abstract void update();
}Integration with Micrometer metrics framework for Spring Boot and cloud-native applications.
/**
* Micrometer metrics tracker factory
*/
public class MicrometerMetricsTrackerFactory implements MetricsTrackerFactory {
/**
* Create factory with MeterRegistry
* @param meterRegistry Micrometer MeterRegistry instance
*/
public MicrometerMetricsTrackerFactory(MeterRegistry meterRegistry);
/**
* Create tracker for specific pool
*/
@Override
public IMetricsTracker create(String poolName, PoolStats poolStats);
}
/**
* Micrometer metrics tracker implementation
*/
public class MicrometerMetricsTracker implements IMetricsTracker {
// Tracks metrics using Micrometer Timer and Counter
}Micrometer Usage Examples:
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory;
// Setup Micrometer with Prometheus
MeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
// Configure HikariCP with Micrometer
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("user");
config.setPassword("pass");
config.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(registry));
config.setPoolName("MyApp-DB"); // Required for metrics labeling
HikariDataSource dataSource = new HikariDataSource(config);
// Metrics are automatically tracked and available in registryMicrometer Metrics Exported:
hikaricp.connections.active - Active connections gaugehikaricp.connections.idle - Idle connections gaugehikaricp.connections.pending - Pending threads gaugehikaricp.connections.total - Total connections gaugehikaricp.connections.min - Minimum connections gaugehikaricp.connections.max - Maximum connections gaugehikaricp.connections.creation - Connection creation timerhikaricp.connections.acquire - Connection acquisition timerhikaricp.connections.usage - Connection usage timerhikaricp.connections.timeout - Connection timeout counterIntegration with Dropwizard Metrics (formerly Codahale Metrics) framework.
/**
* Codahale/Dropwizard 4.x metrics factory
*/
public class CodahaleMetricsTrackerFactory implements MetricsTrackerFactory {
/**
* Create factory with MetricRegistry
* @param registry Dropwizard MetricRegistry
*/
public CodahaleMetricsTrackerFactory(MetricRegistry registry);
/**
* Create factory with MetricRegistry and HealthCheckRegistry
* @param registry Dropwizard MetricRegistry
* @param healthCheckRegistry HealthCheckRegistry for connection health checks
*/
public CodahaleMetricsTrackerFactory(MetricRegistry registry,
HealthCheckRegistry healthCheckRegistry);
}
/**
* Dropwizard 5.x metrics factory
*/
public class Dropwizard5MetricsTrackerFactory implements MetricsTrackerFactory {
/**
* Create factory for Dropwizard 5.x
*/
public Dropwizard5MetricsTrackerFactory(io.dropwizard.metrics5.MetricRegistry registry);
}
/**
* Health check implementation for Codahale metrics
*/
public class CodahaleHealthChecker extends HealthCheck {
/**
* Create health checker for pool
* @param dataSource HikariDataSource to monitor
* @param timeout Health check timeout
*/
public CodahaleHealthChecker(HikariDataSource dataSource, long timeout);
}Dropwizard Usage Examples:
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.zaxxer.hikari.metrics.dropwizard.CodahaleMetricsTrackerFactory;
import com.zaxxer.hikari.metrics.dropwizard.CodahaleHealthChecker;
// Setup Dropwizard metrics
MetricRegistry metricRegistry = new MetricRegistry();
HealthCheckRegistry healthRegistry = new HealthCheckRegistry();
// Configure HikariCP with Dropwizard
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
config.setUsername("user");
config.setPassword("pass");
config.setMetricsTrackerFactory(
new CodahaleMetricsTrackerFactory(metricRegistry, healthRegistry));
config.setPoolName("MyApp-DB");
HikariDataSource dataSource = new HikariDataSource(config);
// Register health check
healthRegistry.register("hikari-pool",
new CodahaleHealthChecker(dataSource, 3000));
// Metrics available in MetricRegistry:
// - pool.Wait (timer) - time to acquire connection
// - pool.Usage (timer) - time connection is borrowed
// - pool.ConnectionCreation (timer) - time to create connection
// - pool.TotalConnections (gauge) - total connections
// - pool.IdleConnections (gauge) - idle connections
// - pool.ActiveConnections (gauge) - active connections
// - pool.PendingConnections (gauge) - pending threadsDirect integration with Prometheus metrics collection.
/**
* Prometheus metrics tracker factory (summary-based)
*/
public class PrometheusMetricsTrackerFactory implements MetricsTrackerFactory {
/**
* Create factory with CollectorRegistry
* @param collectorRegistry Prometheus CollectorRegistry
*/
public PrometheusMetricsTrackerFactory(CollectorRegistry collectorRegistry);
/**
* Create factory with default registry
*/
public PrometheusMetricsTrackerFactory();
}
/**
* Prometheus histogram-based metrics factory
*/
public class PrometheusHistogramMetricsTrackerFactory implements MetricsTrackerFactory {
/**
* Create histogram factory with custom buckets
* @param collectorRegistry Prometheus CollectorRegistry
*/
public PrometheusHistogramMetricsTrackerFactory(CollectorRegistry collectorRegistry);
/**
* Create histogram factory with default registry and buckets
*/
public PrometheusHistogramMetricsTrackerFactory();
}
/**
* Prometheus collector for HikariCP metrics
*/
public class HikariCPCollector extends Collector {
/**
* Create collector for multiple HikariCP pools
*/
public HikariCPCollector();
/**
* Add HikariDataSource to collector
* @param dataSource HikariDataSource to monitor
* @return this collector for chaining
*/
public HikariCPCollector add(String name, HikariDataSource dataSource);
}Prometheus Usage Examples:
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.HTTPServer;
import com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory;
import com.zaxxer.hikari.metrics.prometheus.HikariCPCollector;
// Method 1: Using PrometheusMetricsTrackerFactory
CollectorRegistry registry = CollectorRegistry.defaultRegistry;
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:h2:mem:test");
config.setMetricsTrackerFactory(new PrometheusMetricsTrackerFactory(registry));
config.setPoolName("test-pool");
HikariDataSource dataSource = new HikariDataSource(config);
// Method 2: Using HikariCPCollector (multiple pools)
HikariCPCollector collector = new HikariCPCollector()
.add("primary-db", primaryDataSource)
.add("cache-db", cacheDataSource)
.add("analytics-db", analyticsDataSource);
CollectorRegistry.defaultRegistry.register(collector);
// Start HTTP server for Prometheus scraping
HTTPServer server = new HTTPServer(8080);
// Method 3: Histogram-based metrics (better for percentiles)
config.setMetricsTrackerFactory(
new PrometheusHistogramMetricsTrackerFactory(registry));Prometheus Metrics Exported:
# Connection pool size metrics
hikaricp_active_connections{pool="test-pool"} 5
hikaricp_idle_connections{pool="test-pool"} 3
hikaricp_pending_threads{pool="test-pool"} 0
hikaricp_total_connections{pool="test-pool"} 8
# Timing metrics (summary)
hikaricp_connection_acquire_nanos{pool="test-pool",quantile="0.5"} 1200000
hikaricp_connection_acquire_nanos{pool="test-pool",quantile="0.95"} 5000000
hikaricp_connection_acquire_nanos_count{pool="test-pool"} 1000
hikaricp_connection_acquire_nanos_sum{pool="test-pool"} 1500000000
# Connection usage timing
hikaricp_connection_usage_millis{pool="test-pool",quantile="0.99"} 150
hikaricp_connection_usage_millis_count{pool="test-pool"} 950
# Connection creation timing
hikaricp_connection_creation_millis{pool="test-pool",quantile="0.95"} 50
# Timeout events
hikaricp_connection_timeout_total{pool="test-pool"} 2Create custom metrics integration for other monitoring systems.
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import com.zaxxer.hikari.metrics.PoolStats;
/**
* Custom metrics tracker factory
*/
public class CustomMetricsTrackerFactory implements MetricsTrackerFactory {
private final MyMonitoringSystem monitoringSystem;
public CustomMetricsTrackerFactory(MyMonitoringSystem system) {
this.monitoringSystem = system;
}
@Override
public IMetricsTracker create(String poolName, PoolStats poolStats) {
return new CustomMetricsTracker(poolName, poolStats, monitoringSystem);
}
}
/**
* Custom metrics tracker implementation
*/
public class CustomMetricsTracker implements IMetricsTracker {
private final String poolName;
private final PoolStats poolStats;
private final MyMonitoringSystem monitoring;
public CustomMetricsTracker(String poolName, PoolStats poolStats,
MyMonitoringSystem monitoring) {
this.poolName = poolName;
this.poolStats = poolStats;
this.monitoring = monitoring;
// Start background thread to report pool stats
startStatsReporting();
}
@Override
public void recordConnectionCreatedMillis(long connectionCreatedMillis) {
monitoring.recordTimer("hikari.connection.creation",
connectionCreatedMillis, "pool", poolName);
}
@Override
public void recordConnectionAcquiredNanos(long elapsedAcquiredNanos) {
monitoring.recordTimer("hikari.connection.acquire",
elapsedAcquiredNanos / 1_000_000, "pool", poolName);
}
@Override
public void recordConnectionUsageMillis(long elapsedBorrowedMillis) {
monitoring.recordTimer("hikari.connection.usage",
elapsedBorrowedMillis, "pool", poolName);
}
@Override
public void recordConnectionTimeout() {
monitoring.incrementCounter("hikari.connection.timeout", "pool", poolName);
}
private void startStatsReporting() {
// Report pool statistics periodically
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> {
monitoring.recordGauge("hikari.connections.active",
poolStats.getActiveConnections(), "pool", poolName);
monitoring.recordGauge("hikari.connections.idle",
poolStats.getIdleConnections(), "pool", poolName);
monitoring.recordGauge("hikari.connections.total",
poolStats.getTotalConnections(), "pool", poolName);
}, 0, 30, TimeUnit.SECONDS);
}
@Override
public void close() {
// Cleanup resources
}
}
// Usage
HikariConfig config = new HikariConfig();
config.setMetricsTrackerFactory(new CustomMetricsTrackerFactory(myMonitoringSystem));Configure metrics collection and reporting behavior.
// Enable metrics collection
HikariConfig config = new HikariConfig();
config.setPoolName("MyPool"); // Required for metrics labeling
// Choose metrics implementation
config.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(meterRegistry));
// Alternative: Use metric registry directly (Dropwizard/Codahale)
config.setMetricRegistry(metricRegistry);
// Health check integration (Dropwizard)
config.setHealthCheckRegistry(healthCheckRegistry);
config.addHealthCheckProperty("connectivityCheck", "true");
config.addHealthCheckProperty("expected99thPercentileMs", "100");
HikariDataSource dataSource = new HikariDataSource(config);Metrics Best Practices:
Install with Tessl CLI
npx tessl i tessl/maven-com-zaxxer--hikari-cp