Custom Caches

Using a custom cache can help you improve code performance by storing data that is expensive to calculate, takes a long time to retrieve, or is accessed frequently. You define a custom cache in a JSON file in a custom cartridge.

Approximately 20 MB of memory is reserved for all custom caches on each application server. A B2C Commerce instance can have multiple application servers, but custom caches on different application servers within the same instance are separate and not synchronized across the instance.

A common use case is to cache information that is expensive to calculate. For example, let's suppose that in your storefront, the appearance of a base product depends on the attributes of all its variation products. If any variation product is part of a promotion, the base product displays an On Sale banner. Iterating through all variation products to check whether they’re part of a promotion is an expensive operation that you don't want to repeat every time the base product is displayed, but the information can't be persisted because it could change. A good workaround is to calculate the information and add it to a custom cache for a few minutes.

Another common use case is to cache responses from an external system. For example, in-store availability and prices can be stored on an external system. Instead of making a call to the system every time you need the information, cache the information for a period of time, reducing the number of calls and page load time.

You can also use a custom cache to enable fast access to configuration settings from storefront requests. To implement a configuration-as-code approach, you can retrieve configuration data from an arbritrary source, such as a JSON file from a versioning system, and store that data in a custom cache.

You define a custom cache in a cartridge using a JSON file. You can have up to 100 custom caches across all cartridges in a code version. Any cartridge within a code version can access all the caches defined in all the cartridges of that code version.

You reference the path of the cache definition JSON file in the cartridge's package.json file. The path is relative to the directory where the package.json is located. For example, this entry in the package.json file specifies that the custom caches for the cartridge are defined in a file named caches.json that is in the same directory as the package.json file.

You assign each cache an ID that is unique across all cartridges in a code version. If you use an ID in more than one cartridge in the code version, the cache isn't enabled and an error is logged. You can optionally specify the maximum number of seconds an entry is retained in the cache. This JSON file defines two custom caches: UnlimitedTestCache, which doesn't have an expiration time, and TestCacheWithExpiration, which has an expiration time of 10 seconds.

Problems with invalid cache definitions are reported in the custom error log.

If you change any file in the active code version, or activate a new code version, the content of all custom caches in the code version is cleared. Custom caches are also cleared at the end of data replications or code replications.

To store, retrieve, or manage a cache entry, use the B2C Commerce script API classes dw.system.CacheMgr and dw.system.Cache.

The dw.system.CacheMgr.getCache(cacheID) method returns caches that are already defined.

Entries within the cache are identified by a key. The dw.system.Cache.get(key) method returns the object associated with the key if an entry exists. To specify a scope, such as site or catalog, include a scope reference in the key construction.

A best practice is to populate a cache using dw.system.Cache.get(key, loader), which returns the value associated with the key in the cache or invokes the loader function to generate the entry if no entry is found. You can store an object up to 128 KB in the cache. If the value returned by the loader function is too large, the value isn't stored in the cache but dw.system.Cache.get(key, loader) still returns it. In this case, a log message is written to the custom warn log, and the operation is a "write failure" in the access statistics. No exception is thrown.

The cache can store only JavaScript primitive values and tree-like object structures. A cache can store null but not undefined. Objects retrieved from cache are immutable copies of the entries stored in the cache.

Custom cache content is stored in transient memory. Data isn’t persisted, and there’s no guarantee that an entry can be retrieved from the cache. The storage allocated for entries is limited, and clearing or invalidation could occur at any time.

When using a custom cache, keep in mind that caches in different application servers of the same instance are separate. The dw.system.Cache.invalidate(key) method clears an entry only for the current application server.

For more information about dw.system.CacheMgr and dw.system.Cache, see B2C Commerce Script.