Performance Optimization & Caching with Spring Boot [Java Spring Boot Mastery Series – Part 15]
Performance is critical in enterprise-grade applications. In this part, we’ll explore tools, techniques, and Spring Boot features to improve performance, including caching, lazy loading, asynchronous processing, and profiling.
🚀 Why Performance Optimization?
- Improve response time.
- Reduce server resource usage.
- Handle higher load with fewer resources.
- Deliver a better user experience.
🔁 1. Caching in Spring Boot
Spring Boot supports caching using the @Cacheable, @CachePut, and @CacheEvict annotations.
✅ Step 1: Enable Caching
@SpringBootApplication
@EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
✅ Step 2: Annotate Your Service Method
@Service
public class ProductService {
@Cacheable("products")
public List<Product> getAllProducts() {
simulateDelay(); // Simulates delay
return productRepository.findAll();
}
private void simulateDelay() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
📝 Explanation:
@Cacheable("products"): Caches the result using the method’s parameters as the key.- Subsequent calls return data from cache, avoiding DB hits.
✅ Step 3: Configure Cache (Optional)
Default is simple in-memory cache, but you can use providers like:
- EhCache
- Caffeine
- Redis (distributed caching)
Example: Using Caffeine
<!-- pom.xml -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
# application.yml
spring:
cache:
type: caffeine
caffeine:
spec: maximumSize=500,expireAfterWrite=10m
🔄 2. Lazy Loading in JPA
Use FetchType.LAZY for one-to-many or many-to-many relationships.
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Order> orders;
📝 Explanation:
- Delays loading of child entities until explicitly accessed.
- Reduces initial query load.
🧵 3. Async Processing with @Async
Offload long-running tasks to a separate thread.
Enable Async Support
@SpringBootApplication
@EnableAsync
public class MyApp {}
Create Async Method
@Service
public class EmailService {
@Async
public void sendEmail(String user) {
// long running email logic
}
}
📝 Use Cases:
- Sending emails
- Notification handling
- File processing
📦 Other Optimization Tips
| Technique | Description |
|---|---|
| Connection Pooling | Use HikariCP (default) for efficient DB connections. |
| Query Optimization | Use indexes, native queries when necessary. |
| DTOs over Entities | Avoid exposing entire entities in APIs. |
| Compression | Enable GZIP to reduce response size. |
| Pagination | For large datasets (Spring Data: Pageable). |
| Avoid N+1 Problem | Use @EntityGraph or JOIN FETCH queries. |
🧪 Sample: Enabling GZIP Compression
server:
compression:
enabled: true
mime-types: application/json,application/xml,text/html,text/xml,text/plain
min-response-size: 1024
📌 Summary
Spring Boot provides many built-in and pluggable options to boost performance:
- Use
@Cacheableto reduce redundant DB calls. - Apply lazy fetching in entity relationships.
- Offload work with
@Async. - Monitor system with Actuator + Prometheus.
➡️ Next Up: Part 16 – Real-Time WebSockets and Messaging in Spring Boot
