Start tracking your progress
Trailhead Home
Trailhead Home

Use Org & Session Cache

Learning Objectives

After completing this unit, you’ll be able to:
  • Create a partition.
  • Store and retrieve values in the org and session cache.
  • Describe how long values last in the cache.
  • Handle cache misses.
  • Read session cache from a Visualforce page.

Create a Partition

Note

Note

Don’t have a cache trial yet? This unit requires an active Platform Cache trial. Request a trial using the instructions in the previous unit. If you don’t have a cache trial, you can still carry out the steps in this unit, but your data won’t be found in the cache.

To use Platform Cache, first set up at least one partition. Once you’ve set up partitions, you can add, access, and remove data from them using the Platform Cache Apex API.

Each partition has one session cache and one org cache segment. You can allocate separate capacity to each segment. Usually, you allocate at least 5 MB to your partition. For this example, we aren’t allocating any space to ensure that your code correctly handles cache misses. When no space is allocated, the cache miss rate is 100%, which means that cache values aren’t found in the cache, and the get() method returns null. Consider using this technique to test cache misses. We cover how to handle cache misses in a later section.

To get started, let’s create one partition from the Platform Cache page (available in Salesforce Classic only).

  1. In Setup, enter Platform Cache in the Quick Find box, then select Platform Cache.
  2. Click New Platform Cache Partition.
  3. Give the partition a name (such as the name of your application).
  4. Check Default Partition.
  5. Enter 0 for session cache and 0 for org cache, and then click Save.

    Create a partition

Cache Key Name Format

Each cache key has the following format:

Namespace.Partition.Key

Namespace is the namespace name of the org where the app is running, which can also be set to the special name “local”. The “local” name refers to the namespace of your org whether a namespace is defined in the org or not.

Partition is the name of the partition you created. In this example, it is CurrencyCache.

Key is the name of the key you used to store a value. The key name uniquely represents your cached value.

Let’s say we’d like to store the currency exchange rate from US Dollar to Euro. We can create a key named DollarToEuroRate. For the partition we’ve just created, the full name of the key is:

local.CurrencyCache.DollarToEuroRate

For example, this snippet stores a value in the org cache for the DollarToEuroRate key.

Cache.Org.put('local.CurrencyCache.DollarToEuroRate', '0.91');

The partition we created is a default partition, so you can omit the namespace and partition name and just specify the key name.

DollarToEuroRate

When using a default partition, you can shorten the put() call to the following.

Cache.Org.put('DollarToEuroRate', '0.91');

Store and Retrieve Data in Org Cache

You’ve finished setting up partitions, which is the only step you do in the user interface. Now we’ll switch to Apex to manage the cache. Use org cache to store data that is available to anyone in the org. Either use the Cache.Org class methods, or use the Cache.OrgPartition class to reference a specific partition. Then call the cache methods on that partition.

The following Apex snippet shows how to access a partition using the Cache.OrgPartition class to store and retrieve a cache value for a currency exchange application. It obtains the partition named CurrencyCache in the local namespace. A new value is added with key DollarToEuroRate and today’s currency exchange rate. Next, the value for key DollarToEuroRate is retrieved from the cache.

// Get partition
Cache.OrgPartition orgPart = Cache.Org.getPartition('local.CurrencyCache');

// Add cache value to the partition. Usually, the value is obtained from a 
// callout, but hardcoding it in this example for simplicity.
orgPart.put('DollarToEuroRate', '0.91');

// Retrieve cache value from the partition
String cachedRate = (String)orgPart.get('DollarToEuroRate');

If you’re managing cache values in just one partition, use the Cache.OrgPartition methods. The Cache.OrgPartition methods are easier to use than the Cache.Org methods because you specify the namespace and partition prefix only once when you create the partition object.

Do Cached Values Last Forever?

The previous example assumes that everything goes correctly, namely that:

  • Platform Cache is enabled and has a partition with available space
  • The cached value is found in the cache
  • The value is successfully stored in the cache

But in real life, cached data is not always guaranteed. Platform Cache is intended as a temporary space. For example, the cache might have expired. Even if the cache is still alive, it is possible that your cached data might be evicted from the cache. Just like chipmunks clean out their cheeks to make space for more acorns, Platform Cache also clears some space for more data! When the partition limit is exceeded, Salesforce evicts cached data based on a least recently used (LRU) algorithm. The cache eviction takes place until usage is reduced to less than or equal to 100% capacity. Also, if you exceed the local cache limit, items can be evicted from the local cache before the request has been committed.

Cached Data Duration and Expiration

The amount of time during which data is kept in the cache is called the time-to-live value (ttlsecs). You specify the time-to-live value when you store a key-value pair in the cache using Apex methods. For session cache, your data can live up to 8 hours in the cache. For org cache, your data can live up to 48 hours in the cache. By default, the time-to-live value for org cache is 24 hours.

Session cache expires when its specified time-to-live value is reached or when the user session expires, whichever comes first. Org cache expires when its specified time-to-live value is reached.

Best Practice for Handling Cache Misses

As a best practice, your code should anticipate and accommodate points of failure. In other words, always assume that a cache miss can happen. A cache miss is when you request a value for a key from the cache but the value is not found. The value that your get() call returns is null. Check the result of the get() call for null and handle it accordingly. For example, if the result is null, get the value from the database or an API call.

The following Apex snippet shows how to handle a cache miss by checking whether the returned value from the cache is not null (if (cachedRate != null)). If the value is not null, you can use the value, for example, to display it on a page. Otherwise, fetch this value from another source, such as an API call or from Salesforce.

Cache.OrgPartition orgPart = Cache.Org.getPartition('local.CurrencyCache');
String cachedRate = (String)orgPart.get('DollarToEuroRate');
// Check the cache value that the get() call returned.
if (cachedRate != null) {
    // Display this exchange rate   
} else {
    // We have a cache miss, so fetch the value from the source.
    // Call an API to get the exchange rate.
}

Store and Retrieve Data in Session Cache

Remember what session cache does? That’s right, it stores data that is tied to individual user sessions. For example, you might use session cache in an app to store the user’s favorite currency or a user’s custom navigation tab order. With session cache, you can manage cache values in Apex and read cached values with a Visualforce global variable.

When using Apex, managing the session cache is similar to the way you manage the org cache, except the class names are different. Use the Cache.Session and Cache.SessionPartition classes to access values stored in the session cache. To manage values in any partition, use the methods in the Cache.Session class. If you’re managing cache values in only one partition, use the Cache.SessionPartition methods instead. The Cache.SessionPartition methods are easier to use than the Cache.Session methods because you specify the namespace and partition prefix only once when you create the partition object.

The following snippet of Apex code shows how to access a partition to store and retrieve a cache value. It obtains the partition named CurrencyCache in the local namespace. A new value is added with key FavoriteCurrency. The value for the FavoriteCurrency key is retrieved. The FavoriteCurrency key stores the user’s favorite currency, so this value is different for each user and hence a good candidate for session cache.

// Get partition
Cache.SessionPartition sessionPart = Cache.Session.getPartition('local.CurrencyCache');

// Add cache value to the partition
sessionPart.put('FavoriteCurrency', 'JPY');

// Retrieve cache value from the partition
String cachedRate = (String)sessionPart.get('FavoriteCurrency');

Access Platform Cache with Visualforce Global Variables

Access cached values stored in the platform cache from a Visualforce page by using the $Cache.Session or $Cache.Org global variables. By using these global variables, you can read cached values that were stored with Apex directly from your Visualforce page.

Note

Note

The following examples show how to access the session cache using the $Cache.Session global variable. The equivalent org cache examples are the same except that you use the $Cache.Org global variable instead.

When using the $Cache.Session global variable, fully qualify the key name with the namespace and partition name. This example is an output text component that retrieves a cached value from the namespace ExPro, partition CurrencyCache, and key FavoriteCurrencyRate.

<apex:outputText value="{!$Cache.Session.ExPro.CurrencyCache.FavoriteCurrencyRate}"/>

Unlike with Apex methods, you can’t omit the namespace.partition prefix to reference the default partition in the org. If a namespace isn’t defined for the org, use local to refer to the namespace of the current org where the code is running.

<apex:outputText value="{!$Cache.Session.local.MyPartition.Key}"/>

If the cached value is a data structure that has properties or methods, like an Apex List or a custom class, access those properties in the $Cache.Session expression using dot notation. For example, this markup invokes the List.size() Apex method if the value of numbersList is declared as a List.

<apex:outputText value="{!$Cache.Session.local.MyPartition.numbersList.size}"/>

This example accesses the value property on the myData cache value that is declared as a custom class.

<apex:outputText value="{!$Cache.Session.local.MyPartition.myData.value}"/>

Protected Cache Allocation for ISV Apps

By using platform cache, ISV apps run faster and have better performance. If you’re an ISV developer, you can guarantee cache space for your apps by purchasing cache space for your own namespace. That way, when your app is installed in a subscriber org, the space for your app’s cache is not affected by the usage of the cache in the subscriber’s org. Only Apex code running from your app’s namespace can access and use your namespace’s cache. No other code in the subscriber org can use this cache. You can test your app against your namespace’s cache and be assured that the cache allocation is going to be protected in every subscriber org.

Cache partitions are distributed to subscribers as part of the app’s package. Add one or more cache partitions for your namespace to your package as components in the same way as you add other components. Cache partitions aren’t automatically added as dependent components.

A list of package components that include a cache partition
Note

Note

See the following about packaged partitions.

  • The partitions you add to the package must be nondefault partitions.
  • When a subscriber installs your package, the cache partitions get installed in their org enabling your app to access the installed cache partitions for your namespace.
  • Subscribers must have an Enterprise Edition or Unlimited Edition org, or must have purchased Platform Cache.

The following diagram shows an example cache capacity for an Enterprise Edition subscriber org in which a package was installed with packaged cache. The subscriber’s total cache capacity of 30 MB is divided into three partitions consisting of combinations of session and org cache. The packaged cache capacity originates from the installed package in the subscriber’s org and contains two partitions. The packaged cache consists of 20 MB of cache that the ISV purchased. (Remember, only Apex code from the package can access the packaged cache and code in the subscriber’s org can’t use this cache.)

Cache capacity of packaged partitions and org partitions are separate

Purchase your namespace cache from the Channel Order App. You can purchase cache in 10-MB blocks. To determine how much cache space your apps need, test your apps with your cache partitions. Use trial cache to increase the capacity of cache in your org. As we mentioned in the first unit, certain editions of subscriber orgs get cache allocation by default. For your Developer Edition org in which you develop apps, you can request 10 MB of trial cache. You can request to increase the amount of trial cache given to your org by contacting Salesforce. By experimenting with different cache sizes, you’ll have a better idea of how much cache to purchase for your own namespace.

Now that you’ve seen how to get and store values in Platform Cache, try it on your own! Complete the following challenge to test your knowledge.

Resources

Resources in the Apex Developer Guide:

Resources in the Salesforce Help: Cache Lightning Platform Data

Flower icon used to indicate that the content is for Salesforce Classic

Remember, this module is meant for Salesforce Classic. When you launch your hands-on org, switch to Salesforce Classic to complete this challenge.

retargeting