Spring Boot with Redis

1 minute read

Redis is an in-memory data store — lightning fast. Use it for caching, session storage, rate limiting, and pub/sub messaging.


Setup

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
docker run -d --name bookstore-redis -p 6379:6379 redis:7
spring:
  data:
    redis:
      host: localhost
      port: 6379
  cache:
    type: redis
    redis:
      time-to-live: 600000    # 10 minutes

@Cacheable — Method-Level Caching

@SpringBootApplication
@EnableCaching
public class BookstoreApiApplication { }
@Service
public class BookService {

    @Cacheable(value = "books", key = "#id")
    public BookResponse findById(Long id) {
        // This method is called only on cache MISS
        log.info("Fetching book from database: {}", id);
        Book book = bookRepository.findById(id)
            .orElseThrow(() -> new ResourceNotFoundException("Book", id));
        return BookResponse.from(book);
    }

    @Cacheable(value = "booksByAuthor", key = "#author")
    public List<BookResponse> findByAuthor(String author) {
        return bookRepository.findByAuthor(author).stream()
            .map(BookResponse::from).toList();
    }

    @CacheEvict(value = "books", key = "#id")
    public BookResponse update(Long id, UpdateBookRequest request) {
        // Evicts cached entry when book is updated
        Book book = bookRepository.findById(id).orElseThrow();
        book.setTitle(request.title());
        return BookResponse.from(bookRepository.save(book));
    }

    @CacheEvict(value = {"books", "booksByAuthor"}, allEntries = true)
    public void clearCache() {
        log.info("All caches cleared");
    }

    @CachePut(value = "books", key = "#result.id()")
    public BookResponse create(CreateBookRequest request) {
        // Always executes AND updates cache
        Book book = bookRepository.save(new Book(request.title(), request.author()));
        return BookResponse.from(book);
    }
}
Annotation Behavior
@Cacheable Return cached value if exists, else execute and cache
@CacheEvict Remove from cache
@CachePut Execute and update cache (always runs)

RedisTemplate — Direct Access

@Service
public class RateLimitService {

    private final StringRedisTemplate redisTemplate;

    public RateLimitService(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public boolean isAllowed(String clientIp, int maxRequests, Duration window) {
        String key = "rate:" + clientIp;
        Long count = redisTemplate.opsForValue().increment(key);

        if (count == 1) {
            redisTemplate.expire(key, window);
        }

        return count <= maxRequests;
    }
}

Redis for Session Storage

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
spring:
  session:
    store-type: redis
    redis:
      namespace: bookstore:sessions
    timeout: 30m

Sessions are now stored in Redis — works across multiple app instances (horizontal scaling).


Redis Configuration

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public RedisCacheConfiguration cacheConfiguration() {
        return RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(10))
            .disableCachingNullValues()
            .serializeValuesWith(
                RedisSerializationContext.SerializationPair
                    .fromSerializer(new GenericJackson2JsonRedisSerializer()));
    }
}

Key Takeaways

  1. @EnableCaching + @Cacheable = transparent method caching.
  2. @CacheEvict removes stale data; @CachePut forces update.
  3. RedisTemplate for direct key-value operations (rate limiting, counters).
  4. Redis sessions enable horizontal scaling — session shared across instances.
  5. Always set TTL — cached data should expire.

What’s Next?

Next: Spring Security — authentication, authorization, and securing your API.

Updated: