Redis
Spring Boot 2.0
TTL Configuration
Caching
Java Development

how to configure redis ttl with spring boot 2.0

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In a Spring Boot 2.x application, Redis TTL determines how long cached data survives before Redis evicts it automatically. The right configuration depends on which Redis integration you are actually using: Spring Cache, RedisTemplate, or Spring Data Redis repositories. That distinction matters because TTL is not configured in exactly the same place for each approach.

TTL with Spring Cache and RedisCacheManager

If you are using @Cacheable, the usual place to configure TTL is the Redis cache manager. A global default can be set with RedisCacheConfiguration.

java
1import java.time.Duration;
2import org.springframework.cache.annotation.EnableCaching;
3import org.springframework.context.annotation.Bean;
4import org.springframework.context.annotation.Configuration;
5import org.springframework.data.redis.cache.RedisCacheConfiguration;
6import org.springframework.data.redis.cache.RedisCacheManager;
7import org.springframework.data.redis.connection.RedisConnectionFactory;
8
9@Configuration
10@EnableCaching
11public class RedisCacheConfig {
12
13    @Bean
14    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
15        RedisCacheConfiguration defaults = RedisCacheConfiguration.defaultCacheConfig()
16                .entryTtl(Duration.ofMinutes(10))
17                .disableCachingNullValues();
18
19        return RedisCacheManager.builder(connectionFactory)
20                .cacheDefaults(defaults)
21                .build();
22    }
23}

With that configuration, entries written through Spring's cache abstraction expire after ten minutes unless you override the rule.

Per-Cache TTL Is Often Better Than One Global TTL

Real applications usually need different TTLs for different caches. Sessions, product data, and reference data rarely age at the same rate.

java
1import java.time.Duration;
2import java.util.HashMap;
3import java.util.Map;
4
5@Bean
6public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
7    RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
8            .entryTtl(Duration.ofMinutes(10))
9            .disableCachingNullValues();
10
11    Map<String, RedisCacheConfiguration> cacheConfigs = new HashMap<>();
12    cacheConfigs.put("users", defaultConfig.entryTtl(Duration.ofMinutes(30)));
13    cacheConfigs.put("sessions", defaultConfig.entryTtl(Duration.ofMinutes(5)));
14    cacheConfigs.put("catalog", defaultConfig.entryTtl(Duration.ofHours(6)));
15
16    return RedisCacheManager.builder(connectionFactory)
17            .cacheDefaults(defaultConfig)
18            .withInitialCacheConfigurations(cacheConfigs)
19            .build();
20}

This lets @Cacheable("sessions") and @Cacheable("catalog") expire on different schedules without extra code in the service layer.

Use @Cacheable Normally After TTL Is Configured

Once the cache manager is set up, service code stays simple:

java
1import org.springframework.cache.annotation.Cacheable;
2import org.springframework.stereotype.Service;
3
4@Service
5public class ProductService {
6
7    @Cacheable("catalog")
8    public String getProductName(Long id) {
9        return "product-" + id;
10    }
11}

TTL is not configured on the @Cacheable annotation itself. It comes from the cache manager configuration for that cache.

That is a common source of confusion. Developers often expect TTL to live right next to @Cacheable, but in Spring Cache it usually lives one layer lower.

TTL with RedisTemplate

If you are writing keys directly with RedisTemplate, you set the expiration at write time.

java
1import java.time.Duration;
2import org.springframework.data.redis.core.RedisTemplate;
3import org.springframework.stereotype.Service;
4
5@Service
6public class TokenCacheService {
7    private final RedisTemplate<String, String> redisTemplate;
8
9    public TokenCacheService(RedisTemplate<String, String> redisTemplate) {
10        this.redisTemplate = redisTemplate;
11    }
12
13    public void storeToken(String key, String value) {
14        redisTemplate.opsForValue().set(key, value, Duration.ofMinutes(15));
15    }
16}

This approach is best when TTL depends on the data itself or when you want fine-grained control over individual keys.

TTL with Redis Repositories

If you are using Spring Data Redis repositories rather than the cache abstraction, TTL can also be modeled on the entity side.

java
1import org.springframework.data.annotation.Id;
2import org.springframework.data.redis.core.RedisHash;
3import org.springframework.data.redis.core.TimeToLive;
4
5@RedisHash("loginAttempt")
6public class LoginAttempt {
7    @Id
8    private String id;
9
10    private String username;
11
12    @TimeToLive
13    private Long ttlSeconds;
14
15    public LoginAttempt(String id, String username, Long ttlSeconds) {
16        this.id = id;
17        this.username = username;
18        this.ttlSeconds = ttlSeconds;
19    }
20}

This is a different feature from Spring Cache. It is useful when Redis is acting more like a key-value data store than a transparent cache.

Properties Versus Java Config

Spring Boot also supports Redis cache properties, and in many projects that is enough for a single global TTL. But once you need per-cache settings, serializers, or more control, Java configuration with RedisCacheManager is usually clearer.

The important design question is not "where can I put the number" but "which Redis abstraction am I actually using." TTL follows that abstraction.

Common Pitfalls

One common mistake is expecting @Cacheable itself to have a TTL attribute. It does not. In Spring Cache, TTL is usually configured in the cache manager.

Another mistake is mixing up cache TTL with Redis repository TTL. They are related concepts, but they belong to different APIs.

Developers also sometimes set a global TTL and forget that some caches need much shorter or much longer lifetimes. That can lead to stale data or excessive cache churn.

Finally, if you use RedisTemplate, remember that TTL must be applied when setting the value or through a separate expiration call. Writing the key alone does not automatically make it temporary.

Summary

  • In Spring Boot 2.x, Redis TTL depends on whether you use Spring Cache, RedisTemplate, or Redis repositories.
  • For @Cacheable, configure TTL in RedisCacheManager through RedisCacheConfiguration.
  • Use per-cache TTLs when different caches have different freshness requirements.
  • With RedisTemplate, set expiration directly when writing the key.
  • With Redis repositories, entity TTL can be modeled using @TimeToLive.

Course illustration
Course illustration

All Rights Reserved.