Spring Boot: From Basics to Production · Deployment and Performance
Caching with Spring's Cache Abstraction
Cache expensive reads with @Cacheable and Redis or Caffeine.
Enable caching with @EnableCaching and annotate methods with @Cacheable (read-through), @CachePut (update) and @CacheEvict (invalidate). Choose a provider: Caffeine for fast in-process caches, Redis for shared caches across instances. Set TTLs per cache, cache only data safe to share, and remember annotations work via proxies (self-invocation bypasses them).
@Configuration
@EnableCaching
class CacheConfig {
@Bean
RedisCacheManagerBuilderCustomizer ttl() {
return builder -> builder
.withCacheConfiguration("products", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)))
.withCacheConfiguration("rates", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(60)));
}
}
@Service
class ProductCatalog {
@Cacheable(cacheNames = "products", key = "#id")
public ProductResponse get(long id) { /* DB lookup */ }
@CacheEvict(cacheNames = "products", key = "#id")
public void updatePrice(long id, long priceCents) { /* update */ }
}
Common pitfalls
- Caching per-user data under keys that don't include the user.
- No TTLs, so stale data lives forever.
- Caching mutable entities instead of immutable DTOs.
Key points
- @Cacheable / @CacheEvict
- Caffeine local, Redis shared
- TTL per cache; cache DTOs
Further reading: Spring Boot: Caching
Practice questions
Why might @Cacheable have no effect?
Answer
Caching isn't enabled (@EnableCaching missing), the method is called from within the same class (self-invocation bypasses the proxy), or the method isn't public.
When would you choose Caffeine over Redis?
Answer
For data that's fine to cache per instance with very low latency (configuration, reference data); Redis when caches must be shared across instances or survive restarts.
Open in the app to mark lessons complete, take notes and track your progress.