Careeroza
Caffeine In-Memory Cache
Why Caffeine
Caffeine is a fast in-process cache with size limits, TTL and statistics. It is the best choice when you run one instance, or when slightly different data on different servers is acceptable.
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>Example
application.yml
spring:
cache:
type: caffeine
cache-names: products,productsByCategory
caffeine:
spec: maximumSize=10000,expireAfterWrite=10m,recordStatsDifferent TTL per Cache
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
CacheManager cacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager();
manager.registerCustomCache("products",
Caffeine.newBuilder().maximumSize(10_000).expireAfterWrite(Duration.ofMinutes(10)).recordStats().build());
manager.registerCustomCache("stock",
Caffeine.newBuilder().maximumSize(10_000).expireAfterWrite(Duration.ofSeconds(15)).build());
return manager;
}
}Size-Limited LRU in Plain Java
Example
Caffeine evicts the least useful entries when full. A LinkedHashMap in access order gives a simple LRU with the same idea:
import java.util.*;
public class Main {
public static void main(String[] args) {
LruCache<String, String> cache = new LruCache<>(3);
cache.put("p1", "Pixel 9");
cache.put("p2", "iPhone 16");
cache.put("p3", "Galaxy S25");
cache.get("p1"); // p1 is now most recently used
cache.put("p4", "OnePlus 13"); // full: evicts p2 (least recently used)
System.out.println("keys in cache: " + cache.keySet());
}
}
class LruCache<K, V> extends LinkedHashMap<K, V> {
private final int max;
LruCache(int max) { super(16, 0.75f, true); this.max = max; }
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
boolean evict = size() > max;
if (evict) System.out.println("evicting " + eldest.getKey());
return evict;
}
}Output
evicting p2 keys in cache: [p3, p1, p4]