DEV Community

Cover image for Caching with Redis and Spring Data Redis in Spring Boot
Ayush Shrivastava
Ayush Shrivastava

Posted on

Caching with Redis and Spring Data Redis in Spring Boot

Caching with Redis and Spring Data Redis in Spring Boot

Caching is one of the most effective ways to improve the performance and scalability of modern applications. Instead of querying the database for the same data repeatedly, you can temporarily store frequently accessed data in memory and serve it almost instantly.

One of the most popular technologies for implementing caching is Redis, an in-memory data store known for its speed, flexibility, and reliability.

In this article, you'll learn:

  • What caching is
  • Why Redis is an excellent caching solution
  • How Spring Data Redis works
  • How to configure Redis in Spring Boot
  • How to use @Cacheable, @CachePut, and @CacheEvict
  • Best practices for production applications

Let's get started.


What is Caching?

Caching is the process of storing copies of frequently accessed data in a fast storage layer (cache), so future requests can be served without querying the database.

Without caching:

Client
   │
   ▼
Spring Boot
   │
   ▼
Database
Enter fullscreen mode Exit fullscreen mode

Every request reaches the database.

With caching:

Client
   │
   ▼
Spring Boot
   │
   ▼
Redis Cache
   │
 Cache Hit?
  │     │
 Yes    No
 │       │
 ▼       ▼
Return  Database
          │
          ▼
      Store in Redis
Enter fullscreen mode Exit fullscreen mode

The first request loads data from the database and stores it in Redis.

Subsequent requests are served directly from Redis.

This dramatically reduces latency and database load.


Why Use Redis for Caching?

Redis is one of the fastest key-value stores available because it stores data entirely in memory.

Some major advantages include:

  • Extremely low latency
  • High throughput
  • Rich data structures
  • Optional persistence
  • Replication support
  • Redis Cluster support
  • Automatic expiration (TTL)
  • Pub/Sub messaging
  • Transactions

Because of these features, Redis is widely used in high-performance systems.


What is Spring Data Redis?

Spring Data Redis is part of the Spring Data ecosystem.

It provides:

  • Easy Redis integration
  • Repository support
  • RedisTemplate API
  • Spring Cache integration
  • Serialization support
  • Object mapping
  • Connection management

Instead of writing Redis commands manually, Spring Boot handles most of the complexity for you.


Project Dependencies

Add the following dependencies.

<dependencies>

    <!-- Spring Data Redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <!-- Spring Cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <!-- Jedis Client -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>

</dependencies>
Enter fullscreen mode Exit fullscreen mode

Note: Newer Spring Boot versions use Lettuce as the default Redis client. Unless you specifically need Jedis, Lettuce is generally recommended for production.


Running Redis

Using Docker:

docker run -d \
  --name redis \
  -p 6379:6379 \
  redis:latest
Enter fullscreen mode Exit fullscreen mode

Verify Redis is running:

docker ps
Enter fullscreen mode Exit fullscreen mode

Configure Redis

Create a configuration class.

@Configuration
public class RedisConfig {

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new JedisConnectionFactory();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {

        RedisTemplate<String, Object> template = new RedisTemplate<>();

        template.setConnectionFactory(redisConnectionFactory());

        template.setKeySerializer(new StringRedisSerializer());

        template.setValueSerializer(
                new GenericJackson2JsonRedisSerializer());

        return template;
    }
}
Enter fullscreen mode Exit fullscreen mode

Configure application.properties

spring.data.redis.host=localhost
spring.data.redis.port=6379
Enter fullscreen mode Exit fullscreen mode

If authentication is enabled:

spring.data.redis.password=your-password
Enter fullscreen mode Exit fullscreen mode

Enable Caching

Simply add @EnableCaching to your Spring Boot application.

@SpringBootApplication
@EnableCaching
public class RedisCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(RedisCacheApplication.class, args);
    }

}
Enter fullscreen mode Exit fullscreen mode

Now Spring Boot can automatically manage your cache.


Create the Product Entity

@RedisHash("Product")
public class Product {

    @Id
    private String id;

    private String name;

    private double price;

    // getters and setters

}
Enter fullscreen mode Exit fullscreen mode

Create the Repository

public interface ProductRepository
        extends CrudRepository<Product, String> {
}
Enter fullscreen mode Exit fullscreen mode

Nothing else is required.

Spring Data generates the implementation automatically.


Using Cache Annotations

Spring provides three important annotations:

Annotation Purpose
@Cacheable Reads from cache before executing the method
@CachePut Updates both database and cache
@CacheEvict Removes data from cache

Product Service

@Service
public class ProductService {

    @Autowired
    private ProductRepository repository;

    @Cacheable(value = "products", key = "#id")
    public Product getProductById(String id) {

        System.out.println("Fetching from database...");

        return repository.findById(id).orElse(null);
    }

    @CachePut(value = "products", key = "#product.id")
    public Product updateProduct(Product product) {

        return repository.save(product);
    }

    @CacheEvict(value = "products", key = "#id")
    public void deleteProduct(String id) {

        repository.deleteById(id);
    }

}
Enter fullscreen mode Exit fullscreen mode

Understanding @Cacheable

When the following method is called:

productService.getProductById("1");
Enter fullscreen mode Exit fullscreen mode

Spring checks Redis.

If the key exists

Redis
   │
Found
   │
Return cached object
Enter fullscreen mode Exit fullscreen mode

The database is never accessed.

If the key does not exist

Database
   │
Load object
   │
Store in Redis
   │
Return object
Enter fullscreen mode Exit fullscreen mode

Future requests will use Redis.


Understanding @CachePut

@CachePut(value = "products", key = "#product.id")
Enter fullscreen mode Exit fullscreen mode

Unlike @Cacheable, this annotation always executes the method.

Workflow:

Update Database

↓

Update Redis

↓

Return Updated Object
Enter fullscreen mode Exit fullscreen mode

This ensures your cache remains synchronized.


Understanding @CacheEvict

@CacheEvict(value = "products", key="#id")
Enter fullscreen mode Exit fullscreen mode

When deleting a product:

Delete Database Record

↓

Remove Redis Cache

↓

Done
Enter fullscreen mode Exit fullscreen mode

Without cache eviction, users could still receive stale data.


Testing the Cache

@Component
public class CacheTestRunner implements CommandLineRunner {

    @Autowired
    private ProductService productService;

    @Override
    public void run(String... args) {

        Product product = new Product();

        product.setId("1");
        product.setName("Laptop");
        product.setPrice(999.99);

        productService.updateProduct(product);

        System.out.println(productService.getProductById("1"));

        System.out.println(productService.getProductById("1"));

        product.setName("Gaming Laptop");

        productService.updateProduct(product);

        System.out.println(productService.getProductById("1"));

        productService.deleteProduct("1");

        System.out.println(productService.getProductById("1"));
    }
}
Enter fullscreen mode Exit fullscreen mode

Expected Output

Fetching from database...

Product{id='1', name='Laptop'}

Product{id='1', name='Laptop'}

Product{id='1', name='Gaming Laptop'}

Fetching from database...

null
Enter fullscreen mode Exit fullscreen mode

Notice that "Fetching from database..." appears only when the cache misses.


Cache Lifecycle

Client Request
      │
      ▼
Check Redis
      │
 ┌────┴────┐
 │         │
Hit       Miss
 │         │
 ▼         ▼
Return   Query DB
            │
            ▼
      Save in Redis
            │
            ▼
      Return Response
Enter fullscreen mode Exit fullscreen mode

Production Best Practices

1. Use TTL (Time-To-Live)

Avoid keeping cached data forever.

Example:

spring.cache.redis.time-to-live=10m
Enter fullscreen mode Exit fullscreen mode

2. Cache Only Frequently Accessed Data

Good candidates include:

  • Product catalog
  • User profiles
  • Categories
  • Settings
  • Configuration
  • Country lists

Avoid caching highly volatile data unless necessary.


3. Use Meaningful Cache Names

Instead of:

value="cache1"
Enter fullscreen mode Exit fullscreen mode

Prefer:

value="products"
Enter fullscreen mode Exit fullscreen mode

or

value="users"
Enter fullscreen mode Exit fullscreen mode

4. Serialize JSON

Using:

GenericJackson2JsonRedisSerializer
Enter fullscreen mode Exit fullscreen mode

makes cached objects easier to inspect and maintain.


5. Monitor Cache Performance

Keep an eye on:

  • Cache hit rate
  • Cache miss rate
  • Memory usage
  • Eviction count
  • Response time

Monitoring helps optimize your caching strategy.


Common Cache Annotations

@Cacheable
Enter fullscreen mode Exit fullscreen mode

Reads from cache.


@CachePut
Enter fullscreen mode Exit fullscreen mode

Updates cache.


@CacheEvict
Enter fullscreen mode Exit fullscreen mode

Deletes cache.


@Caching
Enter fullscreen mode Exit fullscreen mode

Combines multiple cache operations.


@CacheConfig
Enter fullscreen mode Exit fullscreen mode

Defines shared cache configuration.


Advantages of Redis Caching

  • Faster response times
  • Reduced database load
  • Better scalability
  • Improved user experience
  • Lower infrastructure costs
  • High availability
  • Distributed caching support

When Should You Use Redis?

Redis is an excellent choice when your application needs:

  • Frequently accessed data
  • High read traffic
  • Low latency
  • Distributed caching
  • Session storage
  • API response caching
  • Rate limiting
  • Leaderboards
  • Real-time analytics

Conclusion

Caching is one of the simplest yet most impactful optimizations you can make in a Spring Boot application. By integrating Redis with Spring Data Redis, you can significantly reduce database load, improve response times, and build applications that scale efficiently under heavy traffic.

Spring Boot's caching abstraction makes implementation straightforward with annotations like @Cacheable, @CachePut, and @CacheEvict, allowing you to focus on business logic rather than cache management.

Whether you're building a REST API, microservices architecture, or a high-traffic web application, Redis caching is a proven strategy to boost performance and deliver a better user experience.

If you're working with Spring Boot in production, learning Redis is a skill that will pay dividends across many real-world applications.

Happy Coding!

Top comments (0)