Boost Performance with Caching in Spring Boot
🚀 **Overview**: Caching is one of the most effective ways to boost the performance of Spring Boot applications. By reducing repetitive database calls, caching improves response time, reduces load on DB, and enhances API efficiency. In this blog, we'll implement caching using `@Cacheable`, `@CacheEvict`, and `Redis`, with a real working example from an Employee & Address management system.
📌 **Why Use Caching?**
- Reduce repeated database queries - Improve API response time - Handle high traffic efficiently - Reduce server resource usage - Improve scalability in microservice environments
1️⃣ **Enable Caching in Spring Boot**
1@SpringBootApplication
2@EnableCaching
3public class EmployeeApplication {
4 public static void main(String[] args) {
5 SpringApplication.run(EmployeeApplication.class, args);
6 }
7}2️⃣ **Using @Cacheable and @CacheEvict in Controller** Below is the controller used for employee CRUD operations with caching applied:
1@RestController
2@RequestMapping("/employee")
3@CacheConfig(cacheNames = "employees")
4public class EmployeeController {
5
6 @Autowired
7 private EmployeeRepository empRepo;
8
9 @PostMapping("/save")
10 @CacheEvict(allEntries = true)
11 public ResponseEntity<Employee> save(@RequestBody Employee employee) {
12
13 if (employee.getAddresses() != null) {
14 employee.getAddresses().forEach(address -> address.setEmployee(employee));
15 }
16
17 Employee saved = empRepo.save(employee);
18 return new ResponseEntity<>(saved, HttpStatus.CREATED);
19 }
20
21 @GetMapping("/all")
22 @Cacheable(key = "'page_' + #page")
23 public ResponseEntity<Page<Employee>> getAll(@RequestParam(defaultValue = "0") int page) {
24 Page<Employee> employees = empRepo.findAll(
25 PageRequest.of(page, 10, Sort.by("id").descending())
26 );
27 return ResponseEntity.ok(employees);
28 }
29
30 @GetMapping("/{id}")
31 @Cacheable(key = "#id")
32 public ResponseEntity<Employee> getById(@PathVariable("id") Integer id) {
33 Employee emp = empRepo.findById(id).get();
34 return ResponseEntity.ok(emp);
35 }
36}3️⃣ **Using @EntityGraph to Avoid N+1 Problem** To prevent lazy-loading issues when fetching employees with their addresses, we use `@EntityGraph` in the repository.
1@Repository
2public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
3
4 @EntityGraph(attributePaths = "addresses")
5 Page<Employee> findAll(Pageable pageable);
6}4️⃣ **Add Redis for High-Performance Caching (Recommended)**
📦 Install Redis locally or use Docker:
1docker run -p 6379:6379 --name redis-cache -d redis📍 Add Redis Starter:
1implementation 'org.springframework.boot:spring-boot-starter-data-redis'📍 Configure Redis in `application.properties`:
1spring.cache.type=redis
2spring.redis.host=localhost
3spring.redis.port=63795️⃣ **What Happens After Applying Caching?**
- First API hit → Fetches data from DB and stores it in Redis - Next API hits → Served directly from cache (much faster!) - When new employee is saved → `@CacheEvict` clears cache - Page-wise cache: `/all?page=0` vs `/all?page=1` are cached separately
⚡ **Performance Boost Observed**:
- Response time reduced by **40–70%** (for paginated queries) - Database load decreased significantly - Improved scalability under load
🎯 **Conclusion**: Caching is a simple yet extremely powerful optimization technique. With Spring Boot, annotations like `@Cacheable`, `@CacheEvict`, and `@CacheConfig` make caching easy to implement. Combined with Redis, your application becomes significantly faster, scalable, and production-ready.
