DEV Community

shantanu mahakale
shantanu mahakale

Posted on

Quick Recap: Caching in Java

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
Enter fullscreen mode Exit fullscreen mode

⚠ 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
}
};
Enter fullscreen mode Exit fullscreen mode

👉 Removes least-used items automatically

👉 Best for lightweight caching


Concurrent Caching

Use ConcurrentHashMap for thread-safe cache:

ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
Enter fullscreen mode Exit fullscreen mode

✔ 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");
Enter fullscreen mode Exit fullscreen mode

✔ 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 {}
Enter fullscreen mode Exit fullscreen mode

Apply Cache:

@Cacheable("users")
public User getUser(int id) {
return userRepo.findById(id); // Runs only once
}
Enter fullscreen mode Exit fullscreen mode

Evict Cache:

@CacheEvict(value="users", allEntries=true)
public void clearCache() {}
Enter fullscreen mode Exit fullscreen mode

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)