Spring Boot Caching Guide
Spring Boot Cache Abstraction
Section titled “Spring Boot Cache Abstraction”Spring Boot provides a cache abstraction that allows you to plug different caching providers without changing application code.
Common Caching Providers
Section titled “Common Caching Providers”| 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 |
Categories
Section titled “Categories”Local Cache
Section titled “Local Cache”- Stored in application memory
- Examples: Caffeine, EhCache
- Extremely fast
- Not shared across application instances
Distributed Cache
Section titled “Distributed Cache”- Shared across multiple application instances
- Example: Redis, Hazelcast
Database Cache
Section titled “Database Cache”- Query results cached
- Example: Hibernate Second-Level Cache
Enable Caching
Section titled “Enable Caching”@SpringBootApplication@EnableCachingpublic class Application {}Spring Cache Annotations
Section titled “Spring Cache Annotations”Comparison
Section titled “Comparison”| 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 |
@Cacheable
Section titled “@Cacheable”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]
@CachePut
Section titled “@CachePut”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@CacheEvict
Section titled “@CacheEvict”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)Integrating Redis with Spring Boot
Section titled “Integrating Redis with Spring Boot”Redis is commonly used for distributed caching in microservices.
Step 1: Add Dependency
Section titled “Step 1: Add Dependency”<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency>Step 2: Configure Redis
Section titled “Step 2: Configure Redis”spring.data.redis.host=localhostspring.data.redis.port=6379(The spring.redis.* prefix was renamed to spring.data.redis.* in Spring Boot 2.3+/3.x.)
Step 3: Enable Caching
Section titled “Step 3: Enable Caching”@EnableCaching@Configurationpublic class CacheConfig {}Step 4: Cache a Method
Section titled “Step 4: Cache a Method”@Cacheable(value = "products", key = "#id")public Product getProduct(Long id) { return productRepository.findById(id).orElse(null);}Architecture
Section titled “Architecture”flowchart TD Client --> Spring["Spring Cache Abstraction"] Spring --> Redis[(Redis Cache)] Redis -->|Cache Miss| DB[(Database)] DB --> Redis Redis --> Client
Preventing Cache Stampede
Section titled “Preventing Cache Stampede”What is Cache Stampede?
Section titled “What is Cache Stampede?”A cache stampede occurs when many concurrent requests reach the database immediately after cached data expires.
Cache expires ->1000 Requests ->Database OverloadPrevention Strategies
Section titled “Prevention Strategies”1. Cache Locking
Section titled “1. Cache Locking”Only one thread rebuilds the cache while others wait.
Thread 1 -> Rebuild CacheThread 2 -> WaitThread 3 -> Wait2. Refresh Ahead
Section titled “2. Refresh Ahead”Refresh cache before expiration.
Example:
TTL = 10 minutesRefresh at 9 minutes3. Randomized TTL
Section titled “3. Randomized TTL”Avoid simultaneous expiration.
TTL = 10 minutes + random(0-2 minutes)4. Asynchronous Reload
Section titled “4. Asynchronous Reload”Use Caffeine’s refreshAfterWrite() capability.
5. Request Coalescing
Section titled “5. Request Coalescing”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
Section titled “Distributed Caching”Distributed caching stores cached data in a shared external system accessible by multiple application instances.
Architecture
Section titled “Architecture”flowchart LR A[Application Instance 1] --> R[(Redis)] B[Application Instance 2] --> R C[Application Instance 3] --> R R --> DB[(Database)]
Benefits
Section titled “Benefits”- Shared across all application instances
- Horizontally scalable
- Improved cache consistency
- Well suited for microservices
Common Distributed Cache Solutions
Section titled “Common Distributed Cache Solutions”| Technology | Primary Use |
|---|---|
| Redis | Most widely used distributed cache |
| Hazelcast | Cluster caching |
| Memcached | High-speed distributed cache |
| Infinispan | Distributed data grid |
Local vs Distributed Cache
Section titled “Local vs Distributed Cache”| 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 |
Typical Production Architecture
Section titled “Typical Production Architecture”flowchart TD Client --> Gateway[API Gateway] Gateway --> Service[Spring Boot Service] Service --> Redis[(Redis Cache)] Redis -->|Miss| Database[(Database)]
Request flow:
- Client request reaches the Spring Boot service.
- Redis is checked for cached data.
- On a cache hit, the cached response is returned.
- On a cache miss, the database is queried.
- The response is stored in Redis.
- The response is returned to the client.
Key Takeaways
Section titled “Key Takeaways”- Spring Boot’s cache abstraction supports multiple cache providers without changing application code.
@Cacheable,@CachePut, and@CacheEvictserve 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.