Language: Java
Performance / Caching
Caching is a key technique to optimize performance and scalability. Ehcache, created in 2003, is a mature and widely-used caching library that supports in-memory, disk, and distributed caching. Caffeine, developed later, provides a high-performance, in-memory cache with efficient algorithms like W-TinyLFU for eviction. Both libraries are used in enterprise Java applications to accelerate data access, reduce latency, and manage load efficiently.
Ehcache and Caffeine are Java caching libraries that improve application performance by storing frequently accessed data in memory, reducing expensive database or API calls. They support in-memory and optionally persistent caching with flexible eviction and expiration policies.
Ehcache:
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.11.9</version>
</dependency>
Caffeine:
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>implementation 'org.ehcache:ehcache:3.11.9'
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'These libraries allow you to store key-value pairs in a cache with expiration, size limits, eviction policies, and optional persistence. Caffeine is highly optimized for low-latency, high-throughput caching, while Ehcache supports more enterprise features including clustering and JMX monitoring.
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, java.util.concurrent.TimeUnit.MINUTES)
.build();
cache.put("key1", "value1");
String value = cache.getIfPresent("key1");
System.out.println(value);Creates a simple Caffeine cache with max size and expiration, then stores and retrieves a value.
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.*;
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(true);
Cache<String, String> cache = cacheManager.createCache("myCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
ResourcePoolsBuilder.heap(100)));
cache.put("key1", "value1");
System.out.println(cache.get("key1"));
cacheManager.close();Creates an Ehcache in-memory cache, adds an entry, retrieves it, and closes the cache manager.
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(100)
.build(key -> "Value for " + key);
System.out.println(cache.get("key1"));Caffeine can automatically compute values if absent using a mapping function.
// Configure Ehcache XML for disk persistence
// Allows cache to survive application restartsEhcache supports persistent caches on disk, useful for storing large datasets.
// Caffeine supports LRU, LFU, and W-TinyLFU eviction policies.
// Ehcache supports LRU, LFU, FIFO and custom policies.Defines how entries are evicted when cache is full or expired.
System.out.println(cache.stats()); // Caffeine
// Ehcache provides JMX beans for monitoring hits, misses, evictionsBoth libraries provide APIs or JMX to monitor cache performance and statistics.
Use caches for frequently accessed, immutable or semi-static data.
Define reasonable size limits and expiration policies to avoid memory issues.
Monitor cache hit/miss ratios to tune performance.
For distributed systems, consider clustered cache options (Ehcache Terracotta, Redis integration).
Avoid caching sensitive data in plaintext unless encrypted.