Skip to content

Spring Boot Caching Guide

Spring Boot provides a cache abstraction that allows you to plug different caching providers without changing application code.

Cache Type Description Use Case
Simple Cache (ConcurrentHashMap) In-memory cache provided by Spring Development/testing
EhCache Java-based high-performance caching Large enterprise apps
Caffeine High-performance local cache Low latency apps
Redis Distributed in-memory cache Microservices / scalable systems
Hazelcast Distributed cache and computation Cluster environments
Infinispan Distributed data grid High-throughput systems
  • Stored in application memory
  • Examples: Caffeine, EhCache
  • Extremely fast
  • Not shared across application instances
  • Shared across multiple application instances
  • Example: Redis, Hazelcast
  • Query results cached
  • Example: Hibernate Second-Level Cache
@SpringBootApplication
@EnableCaching
public class Application {
}

Annotation Purpose Method Execution Typical Use
@Cacheable Read from cache Skipped if cache hit GET APIs
@CachePut Update cache Always executed PUT/Update APIs
@CacheEvict Remove cache Always executed DELETE APIs

Used when reading data.

If the value already exists in the cache, the method is not executed.

@Cacheable(value = "products", key = "#id")
public Product getProduct(Long id) {
return productRepository.findById(id);
}
flowchart TD
A[Request] --> B{Cache Hit?}
B -->|Yes| C[Return Cached Value]
B -->|No| D[Execute Method]
D --> E[Read Database]
E --> F[Store in Cache]
F --> G[Return Result]

Always executes the method and updates the cache.

@CachePut(value = "products", key = "#product.id")
public Product updateProduct(Product product) {
return productRepository.save(product);
}

Flow:

Request -> Method Executes -> Cache Updated

Removes stale cache entries.

@CacheEvict(value = "products", key = "#id")
public void deleteProduct(Long id) {
productRepository.deleteById(id);
}

Evict all entries:

@CacheEvict(value = "products", allEntries = true)

Redis is commonly used for distributed caching in microservices.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring.data.redis.host=localhost
spring.data.redis.port=6379

(The spring.redis.* prefix was renamed to spring.data.redis.* in Spring Boot 2.3+/3.x.)

@EnableCaching
@Configuration
public class CacheConfig {
}
@Cacheable(value = "products", key = "#id")
public Product getProduct(Long id) {
return productRepository.findById(id).orElse(null);
}
flowchart TD
Client --> Spring["Spring Cache Abstraction"]
Spring --> Redis[(Redis Cache)]
Redis -->|Cache Miss| DB[(Database)]
DB --> Redis
Redis --> Client

A cache stampede occurs when many concurrent requests reach the database immediately after cached data expires.

Cache expires
->
1000 Requests
->
Database Overload

Only one thread rebuilds the cache while others wait.

Thread 1 -> Rebuild Cache
Thread 2 -> Wait
Thread 3 -> Wait

Refresh cache before expiration.

Example:

TTL = 10 minutes
Refresh at 9 minutes

Avoid simultaneous expiration.

TTL = 10 minutes + random(0-2 minutes)

Use Caffeine’s refreshAfterWrite() capability.

Merge multiple identical requests into a single backend call.

Interview Answer

Cache stampede happens when multiple concurrent requests hit the database immediately after cache expiry. It can be prevented using locking, refresh-ahead strategies, randomized TTLs, asynchronous cache refresh, and request coalescing.


Distributed caching stores cached data in a shared external system accessible by multiple application instances.

flowchart LR
A[Application Instance 1] --> R[(Redis)]
B[Application Instance 2] --> R
C[Application Instance 3] --> R
R --> DB[(Database)]
  • Shared across all application instances
  • Horizontally scalable
  • Improved cache consistency
  • Well suited for microservices
Technology Primary Use
Redis Most widely used distributed cache
Hazelcast Cluster caching
Memcached High-speed distributed cache
Infinispan Distributed data grid
Feature Local Cache Distributed Cache
Storage Application memory External cache server
Shared Across Instances No Yes
Performance Extremely fast Slight network latency
Example Caffeine Redis

flowchart TD
Client --> Gateway[API Gateway]
Gateway --> Service[Spring Boot Service]
Service --> Redis[(Redis Cache)]
Redis -->|Miss| Database[(Database)]

Request flow:

  1. Client request reaches the Spring Boot service.
  2. Redis is checked for cached data.
  3. On a cache hit, the cached response is returned.
  4. On a cache miss, the database is queried.
  5. The response is stored in Redis.
  6. The response is returned to the client.

  • Spring Boot’s cache abstraction supports multiple cache providers without changing application code.
  • @Cacheable, @CachePut, and @CacheEvict serve different lifecycle stages: read, update, and invalidate.
  • Redis is the preferred distributed cache for scalable Spring Boot microservices.
  • Prevent cache stampedes using locking, refresh-ahead, randomized TTLs, asynchronous reloads, or request coalescing.
  • Distributed caches enable multiple application instances to share a consistent cache while supporting horizontal scaling.