ZIO wrapper for the Caffeine library : https://github.com/ben-manes/caffeine

zcaffeine: ZIO-friendly Caffeine wrapper

GitHub Workflow Status GitHub Maven Central Sonatype Nexus (Snapshots)

zcaffeine is a ZIO-friendly wrapper for the Caffeine cache library.

  • Built for ZIO 2
  • Available for Scala 2.13 and Scala 3


Add the library to your dependencies:

libraryDependencies += "com.stuart" %% "zcaffeine" % "1.0.0-M1"

Snapshots are also published on Sonatype’s snapshots repository.


The ZCaffeine object is the entrypoint for configuring your cache, by using either:

  • A CaffeineSpec, either in its string representation or already loaded
  • An unconfigured builder

Please note that setting that can be configured by a CaffeineSpec can also be configured from the builder, with the builder supporting more options:

  • Setting removal and/or evictions listeners
  • Dynamically setting the expiration of cache entries based on the key & value
  • Enabling scheduling of cache maintenance (rather than running maintenance on cache operations)
  • Compute a cache entry weight dynamically, based on the key & value

After configuration, the cache can be constructed through either:

  • build(): builds a "manually operated" Cache which requires the use of get(key, mappingFunction)/getAll(keys, mappingFunction)/put(key,value) to load or replace values in the cache
  • build(loadOne,loadAll,reloadOne): builds an "automated" LoadingCache cache which offers, along with the other methods from Cache, get(key)/getAll(keys)/refresh/refreshAll that defers to loadOne/loadAll,reloadAll to compute the cache entries

Note: loadAll and reloadOne are optional: both defer to loadOne if missing, but they can set if the behavior should differ (eg. parallel computation in loadAll)


Building a cache

// Configure a cache
val zcaffeine = ZCaffeine[Any, String, String]().map(
        afterCreate = (key, _, _) => key.length.hour,
        afterUpdate = (key, _, _, _) => key.length.minutes,
        afterRead = (_, _, _, _) => Duration.Infinity
val getTime = ZIO.clockWith(_.instant)

// Create a Cache 
val cache = zcaffeine.flatMap(_.build())

// Create a LoadingCache
val loadingCache = zcaffeine.flatMap(
      loadOne = key => getTime.map(time => s"one::$key:$time"),
      loadAll = Some(keys => getTime.map(time => keys.map(key => (key, s"all::$key:$time")).toMap)),
      reloadOne = Some((key, oldValue) => getTime.map(time => s"reload::$key:$oldValue-->$time"))

Using a cache

You can also find additional examples from zcaffeine’s tests.

/*               Using a Cache                */
/* Supposing cache = Cache[Any,String,String] */

// get or compute
// get all or compute all
cache.getAll("key1","key2"))(keys => ZIO.succeed(keys.map(key => (key, key + key)).toMap))
// get only if cached
// insert or replace
cache.put("key", ZIO.succeed("value1"))
// invalidate one
// invalidate all
// invalidate all specified keys

/*               Using a LoadingCache                */
/* Supposing cache = LoadingCache[Any,String,String] */

// get or compute using the functions set while building the cache
// get all or compute all using the functions set while building the cache
// refresh using the functions set while building the cache and get
// refresh all using the functions set while building the cache and get all


This project is published under the Apache 2.0 license.