Caffeine Cache in Spring Boot: Algorithms, Configuration, and Practical Usage
This article introduces Caffeine Cache as a high‑performance local caching solution that improves on Guava Cache by using the W‑TinyLFU eviction algorithm, explains its core concepts, demonstrates manual, synchronous, and asynchronous loading strategies, details eviction policies, and provides step‑by‑step integration and configuration examples for Spring Boot applications.
Caffeine Cache is a modern Java caching library that builds upon the ideas of Guava Cache while offering superior eviction strategies, notably the W‑TinyLFU algorithm, which combines LFU and LRU to achieve near‑optimal hit rates.
1. Algorithm Advantages – W‑TinyLFU
Traditional eviction policies such as FIFO, LRU, and LFU each have drawbacks; FIFO suffers low hit rates, LRU can evict hot items under burst traffic, and LFU struggles with changing access patterns. W‑TinyLFU addresses these issues by using a Count‑Min Sketch with a sliding window to track recent frequencies, allowing the cache to adapt to both steady and bursty workloads.
2. Usage in Java
Caffeine provides three loading strategies:
Manual loading : Use cache.get(key, k -> loadFunction(k)) to compute a value when the key is absent.
Synchronous loading : Build a LoadingCache with a CacheLoader that defines a load method.
Asynchronous loading : Build an AsyncLoadingCache with an AsyncCacheLoader returning a CompletableFuture.
Example of manual loading:
Cache<String, Object> cache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.SECONDS)
.expireAfterAccess(1, TimeUnit.SECONDS)
.maximumSize(10)
.build();
Object value = cache.get(key, k -> computeValue(k));
cache.put("hello", value);
Object present = cache.getIfPresent(key);
cache.invalidate(key);Example of synchronous loading:
LoadingCache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(1, TimeUnit.MINUTES)
.build(k -> loadFromDatabase(k));
Object v = cache.get(key);Example of asynchronous loading:
AsyncLoadingCache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(1, TimeUnit.MINUTES)
.buildAsync(k -> CompletableFuture.supplyAsync(() -> loadAsync(k)));
CompletableFuture<Object> future = cache.get(key);3. Eviction Policies
Caffeine supports size‑based, time‑based, and reference‑based eviction:
Size‑based: maximumSize or maximumWeight (mutually exclusive).
Time‑based: expireAfterAccess, expireAfterWrite, or a custom Expiry implementation.
Reference‑based: weakKeys, weakValues, softValues (soft and weak values cannot be used together).
Removal listeners can be registered to react when entries are evicted:
Cache<String, Object> cache = Caffeine.newBuilder()
.removalListener((key, value, cause) ->
System.out.printf("Key %s was removed (%s)%n", key, cause))
.build();4. Integration with Spring Boot
Since Spring Boot 2.x, Caffeine replaces Guava as the default local cache. To use it:
Add the dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.6.2</version>
</dependency>Enable caching with @EnableCaching on a configuration class.
Configure caches via application.properties or application.yml, e.g.:
spring.cache.cache-names=cache1
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=10sOptionally define a CacheLoader bean when using refreshAfterWrite.
Programmatic cache creation using CaffeineCache and SimpleCacheManager for multiple caches with different TTLs and sizes.
5. Cache Annotations
Spring provides several annotations to work with caches without writing explicit code: @Cacheable: Checks the cache before method execution; if absent, executes the method and stores the result. @CachePut: Always executes the method and updates the cache with the result. @CacheEvict: Removes entries from the cache. @Caching: Combines multiple cache annotations on a single method. @CacheConfig: Shares common cache settings at the class level.
SpEL expressions can be used to define cache keys, conditions, and other attributes, with context variables such as #root.methodName, #args, and #result.
6. Summary
Caffeine offers a flexible, high‑performance caching solution for Java applications, especially when integrated with Spring Boot. Its advanced eviction algorithm, rich configuration options, and seamless annotation support make it suitable for a wide range of backend scenarios.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
