Caching stores frequently accessed data in memory to improve performance and reduce expensive calls (e.g., DB/API). It helps speed up applications and reduce load on resources.
Java provides multiple ways to implement caching — from simple in-memory maps to production-grade caching frameworks.
Why Use Caching?
✔ Improves performance
✔ Reduces DB/API calls
✔ Faster response times
✔ Better scalability
✔ Helps design high-performance systems
Types of Caching
| Cache Type | Description | Example Use Case |
|---|---|---|
| In-Memory | Stored in JVM memory | Java Map, LRU Cache |
| Distributed | Shared across servers | Redis, Hazelcast |
| Local + Remote | Hybrid | Ehcache with DB store |
| Application-Level | Annotations-based | Spring Cache |
Simple In-Memory Cache Using Map
Map<String, String> cache = new HashMap<>();
cache.put("user:1", "John");
cache.get("user:1"); // Fast lookup
⚠ Not thread-safe & no eviction policy.
LRU Cache (Least Recently Used)
Using LinkedHashMap:
LinkedHashMap<K,V> cache = new LinkedHashMap<>(16, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return size() > 100; // Max entries
}
};
👉 Removes least-used items automatically
👉 Best for lightweight caching
Concurrent Caching
Use ConcurrentHashMap for thread-safe cache:
ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
✔ Safe for multi-threaded access
❌ No eviction/TTL built-in
Popular Caching Libraries
| Library | Type | Use Case |
|---|---|---|
| Ehcache | Local / Hybrid | Spring apps, Hibernate |
| Caffeine | In-memory | High-performance LRU/TTL |
| Redis | Distributed | Microservices, APIs |
| Hazelcast | Distributed | Cluster-wide caching |
| Guava Cache | In-memory | Simple TTL, eviction |
Example: Using Caffeine Cache (High Performance)
Cache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
cache.put("user:1", userObject);
cache.getIfPresent("user:1");
✔ Very fast in-memory caching
✔ Supports eviction & TTL
✔ Used in modern Spring Boot apps
Spring Boot Caching (Annotation-Based)
Enable Caching:
@EnableCaching
@SpringBootApplication
public class App {}
Apply Cache:
@Cacheable("users")
public User getUser(int id) {
return userRepo.findById(id); // Runs only once
}
Evict Cache:
@CacheEvict(value="users", allEntries=true)
public void clearCache() {}
Supports: Caffeine, Redis, Ehcache, Hazelcast.
When to Use Which Cache?
| Scenario | Recommended Cache |
|---|---|
| Basic in-memory | HashMap / ConcurrentHashMap |
| LRU logic | LinkedHashMap / Caffeine |
| Spring Boot apps | @Cacheable + Caffeine |
| Microservices | Redis / Hazelcast |
| Distributed apps | Redis / Memcached |
Common Pitfalls
❌ Memory leaks (no eviction)
❌ Stale data issues
❌ Incorrect TTL configuration
❌ Using cache for everything
❌ Cache inconsistency across multiple nodes
Best Practices
✔ Monitor cache hit/miss ratio
✔ Set eviction & TTL policies
✔ Avoid caching large objects
✔ Use caching only for read-heavy data
✔ Prefer Caffeine or Redis for production
Top comments (0)