Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Redis cache TTL versus idle expiry: GETEX changes the read contract

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

Redis cache TTL expires after a write; time-to-idle refreshes on eligible reads and needs an explicit Redis and client contract.

Pick the clock before the annotation

A quote lookup cached for 47 seconds should expire 47 seconds after its last write if it is allowed to become stale regardless of traffic. That is TTL. A session-like lookup that stays alive while actively read needs time-to-idle. Spring Data Redis can opt into idle expiry through Redis GETEX, which reads and resets expiry in one operation. GETEX requires Redis 6.2 or newer. A normal GET from another client does not refresh that idle clock. If one code path uses Spring Cache and another reads Redis directly, the observed lifetime changes with the route taken.

Keep the refresh boundary visible

Configure one cache by name and give it a finite entry TTL. Turn on idle behavior only when every read path participates in the same rule. A cache hit is not an authorization check: include tenant identity in the key and still check the caller's rights. If a quote must become invalid immediately after a price edit, use eviction or a versioned key; waiting for either expiry clock is a business decision.

Test time without a production outage

Write a value, advance beyond the configured TTL, and assert a miss. For idle behavior, read before expiry, advance again, and assert the entry survives only when GETEX was used. Run the test against the actual Redis version, since an in-memory fake cannot establish command support. This is a configuration sketch, not a live Redis test.

Implementation sketch

Java
RedisCacheConfiguration quotes = RedisCacheConfiguration.defaultCacheConfig()
    .entryTtl(Duration.ofSeconds(47))
    .disableCachingNullValues();
// For a separate cache with idle semantics:
RedisCacheConfiguration activeQuotes = quotes.enableTimeToIdle();

Cost and verification

A cache read is one Redis round trip, but idle refresh writes expiry metadata on each GETEX hit. Hot keys stay resident; size and eviction pressure can rise. Expiry does not coordinate concurrent misses across replicas.

Common Mistakes

  • Do not describe TTL as resetting after every cache hit.
  • Do not enable time-to-idle against a Redis server that lacks GETEX.
  • Do not assume a raw GET refreshes an entry's idle expiry.

Read next

Spring cache keys: separate tenants and test the loader count, Spring cache eviction: invalidate the same tenant key used by the read, Spring @Cacheable sync: collapse a local same-key cache miss, Spring Session Redis across replicas: shared login state has a Redis failure boundary.

spring
spring-boot
production
redis-cache-ttl-vs-tti
Storage details