Spring Boot Caching with Redis: Boost Performance with Fast Operations (2025)

    Spring Boot Caching with Redis: Boost Performance with Fast Operations (2025)

    Learn how to integrate Redis caching in Spring Boot with step-by-step setup, configuration, and CRUD examples. This guide covers @Cacheable, @CachePut, @CacheEvict, and @Caching annotations, Redis setup with Docker, and best practices to speed up your application with in-memory caching in 2025.

    default profile

    Munaf Badarpura

    August 22, 2025

    7 min read

    Caching is a powerful technique to enhance the performance of your Spring Boot application by storing frequently accessed data in memory for rapid retrieval. Redis, a high-performance in-memory data store, is an excellent choice for caching due to its speed and scalability.

    In this blog, we’ll explore how to integrate Redis with Spring Boot to implement caching, covering setup, implementation, and key annotations with practical CRUD examples.

    Why Use Caching with Redis?#

    • Performance Boost: Redis stores data in memory, enabling sub-millisecond access times, reducing database load.
    • Scalability: Supports distributed caching, ideal for high-traffic applications.
    • Flexibility: Offers various data structures (strings, hashes, lists, etc.) for versatile caching strategies.
    • Spring Boot Integration: Seamlessly integrates with Spring Boot via Spring Data Redis and caching abstractions.

    Spring Boot Cache Providers#

    Spring Boot supports multiple cache providers through its caching abstraction, allowing developers to switch providers with minimal code changes. Common cache providers include:

    • EhCache: A robust, Java-based cache for local caching, suitable for single-node applications.
    • Caffeine: A high-performance, in-memory cache optimized for Java applications.
    • Redis: An in-memory data store used for distributed caching, offering scalability and persistence options.
    • HazelCast: A distributed cache for clustered environments.
    • Simple: Spring’s default in-memory cache for basic use cases.

    In this blog, we focus on Redis due to its speed, scalability, and seamless integration with Spring Boot.

    What is Redis?#

    Redis (Remote Dictionary Server) is an open-source, in-memory data structure store used as a database, cache, and message broker. Key features include:

    • In-Memory Storage: Stores data in RAM for ultra-fast access.
    • Data Structures: Supports strings, hashes, lists, sets, and more.
    • Persistence: Offers optional disk persistence for data durability.
    • Scalability: Supports replication and clustering for distributed systems.
    • Versatility: Widely used for caching, session management, and real-time analytics.

    Redis is particularly well-suited for caching due to its low-latency data access and ability to handle large-scale, high-throughput workloads.

    How Does Redis Caching Work?#

    Redis caching in Spring Boot works by storing the results of expensive operations (e.g., database queries) in Redis. When a method annotated with caching annotations is called:

    1. Spring checks if the result exists in the Redis cache using a unique key.
    2. If found (cache hit), the cached result is returned, bypassing the method execution.
    3. If not found (cache miss), the method executes, and the result is stored in Redis for future requests.

    Spring’s caching abstraction simplifies this process with annotations like @Cacheable, @CachePut, and @CacheEvict, which we’ll explore later.

    Let's Set Up Our Spring Boot Application!#

    Let’s create a Spring Boot application with Redis caching, implementing CRUD operations with all caching annotations.

    Step 1: Create a Spring Boot Project#

    Use Spring Initializr to generate a project with:

    • Spring Web
    • Spring Data Redis
    • Spring Cache

    Add these dependencies to pom.xml (Maven):

    <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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> </dependencies>

    Step 2: Configure Redis#

    Add Redis connection details to application.properties:

    spring.data.redis.host=localhost spring.data.redis.port=6379 spring.cache.type=redis spring.cache.redis.time-to-live=600000 # Cache TTL in milliseconds (e.g., 10 minutes)

    Start Redis locally or via Docker:

    docker run -d -p 6379:6379 redis

    Step 3: Enable Caching#

    Add @EnableCaching to your main application class to enable Spring’s caching support:

    import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class RedisCachingApplication { public static void main(String[] args) { SpringApplication.run(RedisCachingApplication.class, args); } }

    Step 4: Create a User Model#

    Create a User class to represent the data we’ll cache:

    public class User { private Long id; private String name; private String email; public User() {} public User(Long id, String name, String email) { this.id = id; this.name = name; this.email = email; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }

    Step 5: Create a User Service with CRUD Operations#

    Create a UserService class with caching annotations for CRUD operations:

    import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service public class UserService { private static final String CACHE_NAME = "users"; @Cacheable(value = CACHE_NAME, key = "#id") public User getUserById(Long id) { // Simulate slow database query try { Thread.sleep(2000); // 2-second delay } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return new User(id, "User " + id, "user" + id + "@example.com"); } @CachePut(value = CACHE_NAME, key = "#user.id") public User createUser(User user) { // Simulate database save return new User(user.getId(), user.getName(), user.getEmail()); } @CachePut(value = CACHE_NAME, key = "#id") public User updateUser(Long id, User user) { // Simulate database update return new User(id, user.getName(), user.getEmail()); } @CacheEvict(value = CACHE_NAME, key = "#id") public void deleteUser(Long id) { // Simulate database deletion } }

    Step 6: Create a REST Controller#

    Create a UserController to expose CRUD endpoints:

    import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/users") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping("/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { return ResponseEntity.ok(userService.getUserById(id)); } @PostMapping public ResponseEntity<User> createUser(@RequestBody User user) { return ResponseEntity.ok(userService.createUser(user)); } @PutMapping("/{id}") public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) { return ResponseEntity.ok(userService.updateUser(id, user)); } @DeleteMapping("/{id}") public ResponseEntity<Void> deleteUser(@PathVariable Long id) { userService.deleteUser(id); return ResponseEntity.noContent().build(); } }

    Step 7: Test the Application#

    1. Start the Redis server.
    2. Run the Spring Boot application.
    3. Test endpoints using Postman or curl:
      • GET <http://localhost:8080/api/users/1:> First call takes ~2 seconds; subsequent calls are instant due to caching.
      • POST <http://localhost:8080/api/users> (body: {"id": 2, "name": "John", "email": "john@example.com"}): Creates and caches the user.
      • PUT <http://localhost:8080/api/users/2> (body: {"name": "John Updated", "email": "john.updated@example.com"}): Updates and refreshes the cache.
      • DELETE <http://localhost:8080/api/users/2:> Removes the user from the cache.

    Verify cache contents in Redis CLI:

    redis-cli > KEYS * > GET users::1

    Explanation Of Caching Annotations#

    Spring’s caching annotations simplify cache management. Below are the annotations used in the example, along with @Caching:

    • @Cacheable:
      • Purpose: Caches the result of a method based on its parameters, skipping execution if the result is already cached.
      • Usage in Example: In getUserById, caches the User object with key id in the users cache. Subsequent calls with the same id return the cached result.
      • Example: @Cacheable(value = "users", key = "#id")
    • @CachePut:
      • Purpose: Updates the cache with the method’s result, always executing the method to ensure fresh data.
      • Usage in Example: In createUser and updateUser, updates the cache with the new or modified User object.
      • Example: @CachePut(value = "users", key = "#user.id")
    • @CacheEvict:
      • Purpose: Removes specific entries from the cache to prevent stale data.
      • Usage in Example: In deleteUser, removes the user with the specified id from the cache.
      • Example: @CacheEvict(value = "users", key = "#id")
    • @Caching:
      • Purpose: Groups multiple cache annotations for complex caching logic, allowing multiple cache operations in a single method.
      • Usage: Not used in the example but useful for scenarios requiring combined operations, like updating one cache and evicting another.

    Best Practices for Redis Caching#

    • Set Appropriate TTL: Configure time-to-live (e.g., 10 minutes in the example) to balance performance and data freshness.
    • Use Descriptive Cache Names: Use clear names like users to organize cache entries.
    • Handle Cache Misses: Ensure your application handles scenarios where data isn’t cached gracefully.
    • Monitor Redis: Use tools like RedisInsight to track cache usage and performance.
    • Secure Redis: Enable authentication and TLS for production environments.
    • Evict Strategically: Clear caches when data changes to avoid serving stale data.

    Testing Cache Performance#

    To verify caching effectiveness:

    1. Measure Latency: Use tools like JMeter or curl to compare response times for cached vs. non-cached requests.
    2. Monitor Cache Hits: Use Redis commands like INFO STATS to check cache hit/miss ratios.
    3. Simulate Load: Test under high load to ensure Redis handles concurrent requests efficiently.

    Example: For the GET /api/users/1 endpoint, the first request takes ~2 seconds, while cached requests are near-instant. This demonstrates significant performance improvement.

    Conclusion#

    Redis caching with Spring Boot significantly enhances application performance by reducing database load and latency. Using annotations like @Cacheable, @CachePut, @CacheEvict, and @Caching, you can implement efficient caching for CRUD operations. Redis’s speed and Spring’s abstraction make this a powerful combination for scalable applications.

    Want to Master Spring Boot and Land Your Dream Job?

    Struggling with coding interviews? Learn Data Structures & Algorithms (DSA) with our expert-led course. Build strong problem-solving skills, write optimized code, and crack top tech interviews with ease

    Learn more
    Spring Boot Caching
    Redis Cache Integration In Spring Boot
    Spring Data Redis Tutorial

    Subscribe to our newsletter

    Read articles from Coding Shuttle directly inside your inbox. Subscribe to the newsletter, and don't miss out.

    More articles