A list of cache providers
Tags: java, cache, performance
Published: 2021-10-31 17:28:27

<p>Last week, we described <a href="https://blog.frankel.ch/choose-cache/1/">several criteria to look at to choose a cache</a>.
This week, it’s time to list Java cache providers based on these criteria.</p>
<ul class="sectlevel1">
<li><a href="#java-caching-system">Java Caching System</a></li>
<li><a href="#guava">Guava</a></li>
<li><a href="#caffeine">Caffeine</a></li>
<li><a href="#ehcache">Ehcache</a></li>
<li><a href="#infinispan">Infinispan</a></li>
<li><a href="#coherence-community-edition">Coherence Community Edition</a></li>
<li><a href="#ignite">Ignite</a></li>
<li><a href="#geode">Geode</a></li>
<li><a href="#hazelcast">Hazelcast</a></li>
</ul>
<h2 id="java-caching-system">Java Caching System</h2>
<blockquote>
<p>JCS is a distributed caching system written in Java.
It is intended to speed up applications by providing a means to manage cached data of various dynamic natures.
Like any caching system, JCS is most useful for high read, low put applications.
Latency times drop sharply and bottlenecks move away from the database in an effectively cached system.</p>
-— https://commons.apache.org/proper/commons-jcs/index.html
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://commons.apache.org/proper/commons-jcs/">Java Caching System</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>The Apache Foundation</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/apache/commons-jcs">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2002</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/apache/commons-jcs/commits/master">c6b852c</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>76</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>File-based (<code>cache.ccf</code>)</td>
</tr>
<tr>
  <td>
<pre>jcs.default=
jcs.default.cacheattributes=\
    org.apache.commons.jcs3.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=\
    org.apache.commons.jcs3.engine.memory.lru.LRUMemoryCache</pre>
  </td>
</tr>
<tr>
  <th>Sample code</th>
  <td>
<pre>
var cache =
  JCS.&lt;Long, String&gt;getInstance("cache"); // 1
cache.put(1L, "One");                           // 2
var value = cache.get(1L);                      // 3
System.out.println(value);
JCS.shutdown();                                 // 4
</pre>
<ol>
  <li>Get access to the cache region
  <li>Put
  <li>Get
  <li>Clean up
</tr>
<tr>
  <th>Local/distributed</th>
  <td>Local and distributed</td>
</tr>
<tr>
  <th>Non-blocking</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td><abbr title="Least Recently Used">LRU</abbr></td>
</tr>
<tr>
  <th>Miscellaneous</th>
  <td>
<blockquote>
  <p>The JCS goes beyond simply caching objects in memory. It provides numerous additional features:</p>
  <ul>
    <li>Memory management
    <li>Disk overflow (and defragmentation)
    <li>Thread pool controls
    <li>Element grouping
    <li>Minimal dependencies
    <li>Quick nested categorical removal
    <li>Data expiration (idle time and max life)
    <li>Extensible framework
    <li>Fully configurable runtime parameters
    <li>Region data separation and configuration
    <li>Fine grained element configuration options
    <li>Remote synchronization
    <li>Remote store recovery
    <li>Non-blocking "zombie" (balking facade) pattern
    <li>Lateral distribution of elements via HTTP, TCP, or UDP
    <li>UDP Discovery of other caches
    <li>Element event handling
    <li>Remote server chaining (or clustering) and failover
    <li>Custom event logging hooks
    <li>Custom event queue injection
    <li>Custom object serializer injection
    <li>Key pattern matching retrieval
    <li>Network efficient multi-key retrieval</li></ul>
</blockquote>
</table>

<h2 id="guava">Guava</h2>
<blockquote>
  <p>Guava is a set of core Java libraries from Google that includes new collection types (such as multimap and multiset), immutable collections, a graph library, and utilities for concurrency, I/O, hashing, <strong>caching</strong>, primitives, strings, and more!
  It is widely used on most Java projects within Google, and widely used by many other companies as well.</p>
  — https://github.com/google/guava
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://github.com/google/guava/wiki/CachesExplained">Guava</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>Google</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/google/guava">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2010</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/google/guava/commits/master">ba690ba</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>42.6k</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>Programmatic</td>
</tr>
<tr>
  <td>
<pre>var cache = CacheBuilder.newBuilder()
                        .maximumSize(1000)
                        .build()</pre>
  </td>
</tr>
<tr>
  <th>Sample code</th>
  <td>
<pre>
cache.put(1L, "One");               // 1             
var value = cache.getIfPresent(1L); // 2
System.out.println(value);
cache.cleanUp();                    // 3
</pre>
    <ol>
      <li>Put
      <li>Get
      <li>Clean up
  </td>
</tr>
<tr>
  <th>Local/distributed</th>
  <td>Local</td>
</tr>
<tr>
  <th>Non-blocking</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
    <ul>
    <li><abbr title="First In First Out">FIFO</abbr>
    <li>Weight-based eviction:
One can assign a weight to each entry, according to a custom algorithm, and set the cache a weight limit.
Then, if a new entry would exceed the maximum weight, the "heaviest" entries are removed until the sum of the weights is below the set threshold.
</tr>
<tr>
  <th rowspan="6">Miscellaneous</th>
  <td>Guava is a single JAR that provides cache among many other capabilities</td>
</tr>
<tr>
  <td>A <a href="https://github.com/ocafebabe/guava-jcache">third-party project</a> provides a JCache adapter</td>
</tr>
<tr>
  <td>The <code>get</code> method accepts a <code>Callable</code> parameter that allows to get a value from the cache <strong>or</strong> compute it and store it if it’s not found</td>
</tr>
<tr>
  <td>The <a href="https://github.com/google/guava/wiki/CachesExplained#reference-based-eviction">API</a> uses soft and weak references in keys and values</td>
</tr>
<tr>
  <td>Allows you to attach <a href="https://github.com/google/guava/wiki/CachesExplained#removal-listeners">event handlers</a> when entries are evicted</td>
</tr>
</tbody>
</table>

<h2 id="caffeine">Caffeine</h2>

<blockquote>
<p>Caffeine is a <a href="https://github.com/ben-manes/caffeine/wiki/Benchmarks">high performance</a>, <a href="https://github.com/ben-manes/caffeine/wiki/Efficiency">near optimal</a> caching library.
For more details, see our <a href="https://github.com/ben-manes/caffeine/wiki">user’s guide</a> and browse the <a href="http://www.javadoc.io/doc/com.github.ben-manes.caffeine/caffeine">API docs</a> for the latest release.</p>
— https://github.com/ben-manes/caffeine
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://github.com/ben-manes/caffeine/wiki">Caffeine</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>Ben Manes</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/ben-manes/caffeine">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2014</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/ben-manes/caffeine/commits/master">41abb08</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>10.6k</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>Programmatic</td>
</tr>
<tr>
  <td>
<pre>var cache = Caffeine.newBuilder()
                    .maximumSize(1000)
                    .build()</pre>
  </td>
</tr>
<tr>
  <th>Sample code</th>
  <td>
<pre>
cache.put(1L, "One");                 // 1
var value = cache.getIfPresent(1L);   // 2
System.out.println(value);
cache.cleanUp();                      // 3
</pre>
  <ol>
    <li>Put
    <li>Get
    <li>Clean up
  </td>
</tr>
<tr>
  <th>Local/distributed</th>
  <td>Local</td>
</tr>
<tr>
  <th rowspan="2">Non-blocking</th>
  <td>&#9989;</td>
</tr>
<tr>
  <td>
<pre>var cache = Caffeine.newBuilder()
                    .maximumSize(1000)
                    .&lt;Long, String&gt;buildAsync();        // 1

CompletableFuture<String> future =
    cache.get(1L, k -&gt; expensiveLookup(1L));</pre>
    <ol>
      <li>Build an asynchronous cache</li>
    <ol>
  </td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
    <ul>
      <li><abbr title="First In First Out">FIFO</abbr>
      <li>Weight-based eviction:
One can assign a weight to each entry, according to a custom algorithm, and set the cache a weight limit.
Then, if a new entry would exceed the maximum weight, the "heaviest" entries are removed until the sum of the weights is below the set threshold.</li>
    </ul>
  </td>
</tr>
<tr>
  <th rowspan="2">Miscellaneous</th>
  <td>Caffeine is rewrite of Guava, inspired by its API, but with non-blocking principles at its core.</td>
</tr>
<tr>
  <td>
    <blockquote>
      <ul>
        <li><a href="https://github.com/ben-manes/caffeine/wiki/Population">Automatic loading of entries</a> into the cache, optionally asynchronously
        <li><a href="https://github.com/ben-manes/caffeine/wiki/Eviction#size-based">Size-based eviction</a> when a maximum is exceeded based on <a href="https://github.com/ben-manes/caffeine/wiki/Efficiency">frequency and recency</a>
        <li><a href="https://github.com/ben-manes/caffeine/wiki/Eviction#time-based">Time-based expiration</a> of entries, measured since last access or last write
        <li><a href="https://github.com/ben-manes/caffeine/wiki/Refresh">Asynchronously refresh</a> when the first stale request for an entry occurs
        <li>Keys automatically wrapped in <a href="https://github.com/ben-manes/caffeine/wiki/Eviction#reference-based">weak references</a>
        <li>Values automatically wrapped in <a href="https://github.com/ben-manes/caffeine/wiki/Eviction#reference-based">weak or soft references</a>
        <li><a href="https://github.com/ben-manes/caffeine/wiki/Removal">Notification</a> of evicted (or otherwise removed) entries
        <li><a href="https://github.com/ben-manes/caffeine/wiki/Compute">Writes propagated</a> to an external resource
        <li>Accumulation of cache access <a href="https://github.com/ben-manes/caffeine/wiki/Statistics">statistics</a></li>
      </ul>
    </blockquote>
  </td>
</tr>
</tbody>
</table>

<h2 id="ehcache">Ehcache</h2>

<blockquote>
<p>Ehcache is an open source, standards-based cache that boosts performance, offloads your database, and simplifies scalability.
It’s the most widely-used Java-based cache because it’s robust, proven, full-featured, and integrates with other popular libraries and frameworks.
Ehcache scales from in-process caching, all the way to mixed in-process/out-of-process deployments with terabyte-sized caches.</p>
-— https://www.ehcache.org/
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://www.ehcache.org/">Ehcache</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>Software AG</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/ehcache/ehcache3">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2009</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/ehcache/ehcache3">212c63c</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>1.7k</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>Programmatic</td>
</tr>
<tr>
  <td>
<pre>var cacheManager = CacheManagerBuilder
    .newCacheManagerBuilder()
    .withCache(
        "cache",
        CacheConfigurationBuilder.newCacheConfigurationBuilder(
            Long.class,
            String.class,
            ResourcePoolsBuilder.heap(10)
        )
    ).build();
cacheManager.init();
var cache = cacheManager.getCache(
    "cache", Long.class, String.class
);</pre>
  </td>
</tr>
<tr>
  <th>Sample code</th>
  <td>
<pre>cache.put(key, value);         // 1 
var value = cache.get(key);         // 2
cacheManager.close();               // 3</pre>
  <ol>
    <li>Put
    <li>Get
    <li>Clean up
  </td>
</tr>
<tr>
  <th>Local/distributed</th>
  <td>Local</td>
</tr>
<tr>
  <th>Non-blocking</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
<ul><li><abbr title="Least Recently Used">LRU</abbr>
    <li><abbr title="Least Frequently Used">LFU</abbr>
    <li><abbr title="First In First Out">FIFO</abbr>
    <li>Pluggable policy:
EhCache provides an API to write your own eviction policy</li></ul></td>
</tr>
<tr>
  <th rowspan="2">Miscellaneous</th>
  <td>Ehcache 3.x is a complete rewrite from Ehache 2.x</td>
</tr>
<tr>
  <td>Terracota is the Enterprise version of Ehcache.
It provides distributed capabilities.</td>
</tr>
</tbody>
</table>


<div class="sect1">
<h2 id="infinispan">Infinispan</h2>
<blockquote>

<p>Infinispan is an open-source in-memory data grid that offers flexible deployment options and robust capabilities for storing, managing, and processing data.
Infinispan provides a key/value data store that can hold all types of data, from Java objects to plain text.
Infinispan distributes your data across elastically scalable clusters to guarantee high availability and fault tolerance, whether you use Infinispan as a volatile cache or a persistent data store.</p>

— https://infinispan.org/
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://infinispan.org/">Infinispan</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>RedHat</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/infinispan/infinispan">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2009</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/infinispan/infinispan">3dd18ce</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>910</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>Programmatic</td>
</tr>
<tr>
  <td>
<pre>var cacheManager = new DefaultCacheManager();
cacheManager.defineConfiguration("cache",
    new ConfigurationBuilder().memory().maxSize("1000").build()
);
var cache = cacheManager.&lt;Long, String&gt;getCache("cache");</pre>
  </td>
</tr>
<tr>
  <th>Sample code</th>
  <td>
<pre>
cache.put(1L, "One");               // 1
var value = cache.get(1L);          // 2
System.out.println(value);
cacheManager.close();               // 3
</pre>
  <ol>
    <li>Put
    <li>Get
    <li>Clean up
  </td>
</tr>
<tr>
  <th>Local/distributed</th>
  <td>Local and distributed</td>
</tr>
<tr>
  <th rowspan="2">Non-blocking</th>
  <td>&#9989;</td>
</tr>
<tr>
  <td>
<pre>CompletableFuture&lt;String&gt; future =
    cache.getAsync(1L, k -&gt; expensiveLookup(1L));</pre>
  </td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
<p><abbr title="Least Frequently Used">LFU</abbr></p>
</td>
</tr>
<tr>
  <th rowspan="2">Miscellaneous</th>
  <td>Infinispan is the successor of JBoss Cache</td>
</tr>
<tr>
  <td>
    <blockquote>
      <ul>
        <li>Interoperability: access data across multiple protocols and programming languages
        <li>Resilient and Fault Tolerant Data: ensure data is always available to meet demanding workloads
        <li>ACID Transactions: guarantee that data is always valid and consistent
        <li>Clustered Processing: process data in real-time without burdening resources
        <li>Queries: perform simple, accurate, and fast searches across distributed data sets</li>
      </ul>
    </blockquote>
  </td>
</tr>
</tbody>
</table>

<h2 id="coherence-community-edition">Coherence Community Edition</h2>

<blockquote>
<p>Coherence is scalable, fault-tolerant, cloud-ready, distributed platform for building grid-based applications and reliably storing data.
The product is used at scale, for both compute and raw storage, in a vast array of industries such as critical financial trading systems, high performance telecommunication products, and eCommerce applications.</p>

—- https://coherence.community/latest/21.06/docs/
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://coherence.community/">Coherence</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>Oracle</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/oracle/coherence">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="https://oss.oracle.com/licenses/upl/">Universal Permissive License</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2001</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/oracle/coherence/commits/master">5f0b968</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>340</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>File-based</td>
</tr>
<tr>
  <td>
<pre>
&lt;?xml version="1.0"?&gt;
&lt;cache-config&gt;
    &lt;caching-scheme-mapping&gt;
        &lt;cache-mapping&gt;
            &lt;cache-name&gt;cache&lt;/cache-name&gt;
            &lt;scheme-name&gt;local&lt;/scheme-name&gt;
        &lt;/cache-mapping&gt;
    &lt;/caching-scheme-mapping&gt;
    &lt;caching-schemes&gt;
        &lt;local-scheme&gt;
            &lt;scheme-name&gt;local&lt;/scheme-name&gt;
            &lt;high-units&gt;1000&lt;/high-units&gt;
        &lt;/local-scheme&gt;
    &lt;/caching-schemes&gt;
&lt;/cache-config&gt;
</pre>
  </td>
</tr>
<tr>
  <th>Sample code</th>
  <td>
<pre>
var cache = CacheFactory.&lt;Long, String&gt;getCache("cache"); // 1
cache.put(1L, "One");        // 2
var value = cache.get(1L);   // 3
System.out.println(value);
cache.close();               // 4
</pre>
    <ol>
      <li>Get a reference to the cache
      <li>Put
      <li>Get
      <li>Clean up
  </td>
</tr>
<tr>
  <th>Local/distributed</th>
  <td>Local and distributed</td>
</tr>
<tr>
  <th rowspan="2">Non-blocking</th>
  <td>&#9989;</td>
</tr>
<tr>
  <td>
<pre>var cache = CacheFactory
                .&lt;Long, String&gt;getCache("cache")
                .async();
CompletableFuture<String> future = cache.get(1L);</pre>
  </td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
    <ul>
      <li><abbr title="Most Frequently Used">MFU</abbr> and <abbr title="Most Recently Used">MRU</abbr> scaled on a logarithmic curve
      <li><abbr title="Least Recently Used">LRU</abbr>
      <li><abbr title="Least Frequently Used">LFU</abbr>
      <li>Pluggable policy: EhCache provides an API to write your own eviction policy</li></ul></td>
</tr>
<tr>
  <th rowspan="3">Miscellaneous</th>
  <td>Oracle bought Coherence from Tangsol in 2007</td>
</tr>
<tr>
  <td>
    <p>Commercial versions are available:</p>
    <ul>
      <li>Standard
      <li>Enterprise
      <li>Grid
    </ul>
  </td>
</tr>
<tr>
  <td>
    <ul>
      <li>Clustering and Data Sharding
      <li>Scalability and High Avalability
      <li>Disk-Based Persistence
      <li>Key-Value Data Store
      <li>Parallel Queries
      <li>Efficient Aggregation
      <li>In-Place Processing
      <li>Sophisticated Event Model</li>
    </ul>
  </td>
</tr>
</tbody>
</table>

<h2 id="ignite">Ignite</h2>

<blockquote>
<p>Distributed Database For High-Performance Computing With In-Memory Speed</p>

-- https://ignite.apache.org/
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://ignite.apache.org/">Ignite</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>GridGain</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/apache/ignite">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>?</td>
</tr>
<tr>
  <th>Open-Sourced</th>
  <td>2014</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/apache/ignite/commits/master">73a687d</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>4k</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>Programmatic</td>
</tr>
<tr>
  <td>
<pre>var cacheCfg = new CacheConfiguration&lt;Long, String&gt;();
cacheCfg.setOnheapCacheEnabled(true);
cacheCfg.setEvictionPolicyFactory(
    () -&gt; new LruEvictionPolicy&lt;&gt;(1000)
);
cacheCfg.setName("cache");
var cfg = new IgniteConfiguration();
cfg.setCacheConfiguration(cacheCfg);
ignite = Ignition.start(cfg);
var cache = ignite.getOrCreateCache("cache");</pre>
  </td>
</tr>
<tr>
  <th>Code sample</th>
  <td>
<pre>
cache.put(1L, "One");             // 1
var value = cache.get(1L);        // 2
System.out.println(value);
ignite.close();                   // 3
</pre>
    <ol>
      <li>Put
      <li>Get
      <li>Clean up
  </td>
</tr>
<tr>
  <th rowspan="2">Non-blocking</th>
  <td>&#9989;</td>
</tr>
<tr>
  <td>
<pre>
IgniteFuture&lt;String&gt; future = cache.getAsync(1L); // 1</pre>
    <ol><li>Ignite provides its own asynchronous primitives, which are different from the JDK’s</li></ol>
  </td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#9989; (provided by Ignite)</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
    <ul>
      <li><abbr title="Least Recently Used">LRU</abbr>
      <li><abbr title="First In First Out">FIFO</abbr>
      <li>Sorted:
      Entries are removed in order, so that they need to implement <code>Comparable</code> or you need to configure you own <code>Comparator</code> implementation</li>
    </ul>
  </td>
</tr>
<tr>
  <th rowspan="2">Miscellaneous</th>
  <td>
    <blockquote>
      <p>Core features:</p>
      <ul>
          <li>Distributed SQL
          <li>Multi-tier Storage
          <li>Co-located Compute
          <li>ACID Transactions
          <li>Machine Learning
          <li>Continuous Queries</li>
      </ul>
    </blockquote>
  </td>
</tr>
<tr>
  <td>GridGrain offers an enterprise version of Ignite named GridGain In-Memory Computing Platform</td>
</tr>
</tbody>
</table>

<h2 id="geode">Geode</h2>

<blockquote>
<p>Apache Geode is a data management platform that provides real-time, consistent access to data-intensive applications throughout widely distributed cloud architectures.</p>
<p>Apache Geode pools memory, CPU, network resources, and optionally local disk across multiple processes to manage application objects and behavior.
It uses dynamic replication and data partitioning techniques to implement high availability, improved performance, scalability, and fault tolerance.
In addition to being a distributed data container, Apache Geode is an in-memory data management system that provides reliable asynchronous event notifications and guaranteed message delivery.</p>

-- https://github.com/apache/geode
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://geode.apache.org/">Geode</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>Pivotal</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/apache/geode">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2015</td>
</tr>
<tr>
  <th>Open-Sourced</th>
  <td>2019</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/apache/geode/commits/develop">a21df0b</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>2k</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>File-based and programmatic</td>
</tr>
<tr>
  <td>
<pre>var cache = new CacheFactory().create();
var factory = cache.&lt;Long, String&gt;createRegionFactory();
factory.setEvictionAttributes(
    EvictionAttributes.createLRUEntryAttributes(1000)
);
var region = factory.create("cache");</pre>
  </td>
</tr>
<tr>
  <th>Code sample</th>
  <td>
<pre>
region.put(1L, "One");         // 1 
var value = region.get(1L);    // 2
System.out.println(value);
cache.close();                 // 3
</pre>
    <ol>
      <li>Put
      <li>Get
      <li>Clean up
  </td>
</tr>
<tr>
  <th>Non-blocking</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#10060;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
<p><abbr title="Least Recently Used">LRU</abbr></p>
</td>
</tr>
<tr>
  <th rowspan="2">Miscellaneous</th>
  <td>GemStone is the company that initially developed Geode. In 2010, SpringSource acquired GemStone.</td>
</tr>
<tr>
  <td>
    <blockquote>
      <p>[...] <a href="https://geode.apache.org/docs/guide/114/getting_started/product_intro.html">main features and key functionality</a>:</p>
      <ul>
        <li>High Read-and-Write Throughput
        <li>Low and Predictable Latency
        <li>High Scalability
        <li>Continuous Availability
        <li>Reliable Event Notifications
        <li>Parallelized Application Behavior on Data Stores
        <li>Shared-Nothing Disk Persistence
        <li>Reduced Cost of Ownership
        <li>Single-Hop Capability for Client/Server
        <li>Client/Server Security
        <li>Multisite Data Distribution
        <li>Continuous Querying
        <li>Heterogeneous Data Sharing</li>
      </ul>
    </blockquote>
  </td>
</tr>
</tbody>
</table>

<h2 id="hazelcast">Hazelcast</h2>

<p>I work for Hazelcast at the time of this writing.</p>

<blockquote>
<p>Hazelcast is a streaming and memory-first application platform for fast, stateful, data-intensive workloads on-premises, at the edge or as a fully managed cloud service.</p>
—- https://hazelcast.com/
</blockquote>

<table>
<tbody>
<tr>
  <th>Name</th>
  <td><a href="https://hazelcast.com/">Hazelcast</a></td>
</tr>
<tr>
  <th>Provider</th>
  <td>Hazelcast</td>
</tr>
<tr>
  <th>Source</th>
  <td><a href="https://github.com/hazelcast/hazelcast">GitHub</a></td>
</tr>
<tr>
  <th>License</th>
  <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a></td>
</tr>
<tr>
  <th>Inception date</th>
  <td>2008</td>
</tr>
<tr>
  <th>Last commit</th>
  <td><a href="https://github.com/hazelcast/hazelcast/commits/master">de91d6b</a></td>
</tr>
<tr>
  <th>GitHub stars</th>
  <td>4.6k</td>
</tr>
<tr>
  <th rowspan="2">Configuration</th>
  <td>File-based and programmatic</td>
</tr>
<tr>
  <td>
<pre>var hazelcast = Hazelcast.newHazelcastInstance();
hazelcast.getConfig()
         .getMapConfig("cache")
         .getEvictionConfig()
         .setSize(1000);
var map = hazelcast.getMap("cache");</pre>
  </td>
</tr>
<tr>
  <th>Code sample</th>
  <td>
<pre>
map.put(1L, "One");               // 1 
var value = map.get(1L);          // 2
System.out.println(value);
hazelcast.shutdown();             // 3
</pre>
    <ol>
      <li>Put
      <li>Get
      <li>Clean up
  </td>
</tr>
<tr>
  <th rowspan="2">Non-blocking</th>
  <td>&#9989;</td>
</tr>
<tr>
  <td>
<pre>CompletionStage&lt;String&gt; stage = cache.getAsync(1L);</pre>  
  </td>
</tr>
<tr>
  <th>JCache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Spring Cache</th>
  <td>&#9989;</td>
</tr>
<tr>
  <th><abbr title="Time-to-Live">TTL</abbr></th>
  <td>&#9989;</td>
</tr>
<tr>
  <th>Eviction strategies</th>
  <td>
    <ul>
      <li><abbr title="Least Recently Used">LRU</abbr>
      <li><abbr title="Least Frequently Used">LFU</abbr>
      <li>Pluggable policy:
Hazelcast provides an API to write your own eviction policy</li></ul>
  </td>
</tr>
<tr>
  <th rowspan="2">Miscellaneous</th>
  <td>Hazelcast provides an Enterprise edition with additional features</td>
</tr>
<tr>
  <td>
    <blockquote>
      <ul>
        <li>Distributed computation, data structures, and events
        <li>Streaming data processing
        <li>Connectors to read from/write to systems like Apache Kafka, JMS, JDBC and HDMS
        <li>Querying with SQL and predicates
        <li>CP subsystem for distributed coordination use cases
        <li>JCache implementation
        <li>Replication of web sessions (filter, Tomcat, Jetty based)
        <li>Administration and monitoring utilities including Management Center, JMX, metrics and diagnostics</li>
      </ul>
    </blockquote>
</td>
</tr>
</tbody>
</table>

<p>The following Maven project shows a simple key get-put for each cache.</p>

{% github ajavageek/cacheproviders %}

<p>I tried my best to provide accurate objective information.
Please let me know in the comments if something is wrong.</p>

<p><strong>To go further:</strong>
<ul>
  <li><a href="https://blog.frankel.ch/choose-cache/1/">How to choose a cache</a></li>
  <li><a href="https://medium.com/outbrain-engineering/oh-my-guava-we-are-moving-to-caffeine-99387819fdbb">Oh my Guava! We are moving to Caffeine</a></li>
  <li><a href="https://db-engines.com/en/system/Ehcache%3BGeode%3BHazelcast%3BIgnite%3BOracle+Coherence">System Properties Comparison</a></li>
</ul>

_Originally published at [A Java Geek](https://blog.frankel.ch/choose-cache/2/) on October 31<sup>st</sup>, 2021_