Databases 15 min read

Why Your JedisPool Keeps Recreating Connections and How to Fix It in Spring Boot

This article investigates why a Spring Boot application using JedisPool experiences high connection‑acquisition latency, analyzes the Evictor logic and mis‑configured pool parameters, and presents a custom configuration solution that stabilizes the pool and eliminates repeated connection creation and destruction.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Why Your JedisPool Keeps Recreating Connections and How to Fix It in Spring Boot

Background

The author previously wrote an article on troubleshooting high Redis latency by configuring a stable connection pool. Recent load‑testing still shows requests blocked while acquiring connections from JedisPool, leading to overall request timeouts.

Problem 1: Persistent Jedis Connection Timeouts

Even with a pool configured as spring.redis.jedis.pool.max-active=500, max-idle=500, min-idle=500, and heartbeat checks enabled, the maximum wait time for a connection remains above 900 ms. Metrics show large createdCount and destroyedCount values, indicating frequent connection recreation.

Analysis of Pool Parameters

spring.redis.jedis.pool.max-active=500 // 4 servers × 500 = 2000 < 30000 (Redis limit)</code>
<code>spring.redis.jedis.pool.max-idle=500</code>
<code>spring.redis.jedis.pool.min-idle=500 // stable pool size</code>
<code>spring.redis.jedis.pool.test-while-idle=true // periodic health check</code>
<code>spring.redis.jedis.pool.time-between-eviction-runs-millis=30000</code>
<code>spring.redis.jedis.pool.num-tests-per-eviction-run=-1 // test all idle connections each run</code>
<code>spring.redis.jedis.pool.min-evictable-idle-time-millis=-1 // prevent idle‑time based eviction

Despite these settings, the destroyedCount and destroyedByEvictorCount are identical, meaning the Evictor is responsible for all connection removals.

Evictor Logic

The core Evictor code resides in org.apache.commons.pool2.impl.GenericObjectPool#evict. It removes connections when either the idle time exceeds a threshold or the Redis heartbeat fails.

Is Idle Timeout the Cause?

Configuration shows min-evictable-idle-time-millis is set to Long.MAX_VALUE in the article, but the actual default in JedisPoolConfig is 60000 ms, causing connections idle for more than 60 s to be evicted.

Is Redis Heartbeat Failure the Cause?

Local ping tests show normal latency, so heartbeat failures are unlikely.

Root Cause

The Evictor runs every 30 s, evicting idle connections after 60 s, and JedisPool uses LIFO ordering by default, which repeatedly destroys and recreates the same connections.

Why LIFO Matters

With LIFO, returned connections are placed at the head of the pool, while borrowed connections are taken from the tail, leading to a cycle of Create → Idle → minIdle(60s) → Destroy → Create.

Failed Work‑arounds

Upgrading Spring Boot does not expose min-evictable-idle-time-millis in RedisProperties.Pool.

Switching the pool to FIFO via setLifo(false) still suffers from the same missing configuration.

Disabling or lengthening the Evictor interval removes idle‑based evictions but also disables automatic reconnection after Redis failures.

Effective Solution (Solution 4)

Implement a custom JedisClientConfigurationBuilderCustomizer to inject the missing parameters ( min-evictable-idle-time-millis, num-tests-per-eviction-run, lifo, etc.) into the pool configuration.

public JedisPoolConfig jedisPoolConfig(RedisProperties.Pool pool) {</code>
<code>    JedisPoolConfig config = new JedisPoolConfig();</code>
<code>    config.setMaxTotal(pool.getMaxActive());</code>
<code>    config.setMaxIdle(pool.getMaxIdle());</code>
<code>    config.setMinIdle(pool.getMinIdle());</code>
<code>    if (pool.getTimeBetweenEvictionRuns() != null) {</code>
<code>        config.setTimeBetweenEvictionRunsMillis(pool.getTimeBetweenEvictionRuns().toMillis());</code>
<code>    }</code>
<code>    if (pool.getMaxWait() != null) {</code>
<code>        config.setMaxWaitMillis(pool.getMaxWait().toMillis());</code>
<code>    }</code>
<code>    // custom properties injected here</code>
<code>    return config;</code>
<code>}

Verification

After applying the customizer, the pool remains stable: connection‑acquisition latency drops from >900 ms to a few tens of milliseconds, and the nightly load‑test timeout disappears.

Summary of Steps

Configure core pool properties supported by Spring Boot.

Implement a JedisClientConfigurationBuilderCustomizer to add unsupported properties such as min-evictable-idle-time-millis, num-tests-per-eviction-run, and lifo.

Validate that the pool no longer destroys and recreates connections under normal load.

References: [1] Spring Boot RedisProperties source [2] Jedis issue discussing connection recreation [3] GitHub issue for adding more Jedis pool properties

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

redisSpringBootConnectionPoolingEvictorJedisPool
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

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.