Server-Side Web-Tier Caching
One of the Commerce Cloud application layer components performs web-tier caching of SCAPI requests, which affects GET requests to various API families.
This server-side caching mechanism, is only employed after a request reaches the Commerce Cloud server-side application layer. If there is another caching mechanism in place (for example, on the client side), it is still used independently. This has to be considered when dealing with multiple layers of caching on the front-end or client side of a storefront implementation.
Responses to GET requests of the following APIs are cached:
- /product/shopper-products/v1/organizations/{org-id}/categories/{id}
- /product/shopper-products/v1/organizations/{org-id}/categories
- /product/shopper-products/v1/organizations/{org-id}/products/{id}
- /product/shopper-products/v1/organizations/{org-id}/products
- /search/shopper-search/v1/organizations/{org-id}/product-search
- /search/shopper-search/v1/organizations/{org-id}/search-suggestions
- /pricing/shopper-promotions/v1/organizations/{org-id}/promotions/campaigns
- /pricing/shopper-promotions/v1/organizations/{org-id}/promotions/campaigns
- /site/shopper-seo/v1/organizations/{org-id}/url-mapping
- /configuration/preferences/v1/organizations/{org-id}/site-custom-preferences?{siteId}
- /configuration/preferences/v1/organizations/{org-id}/global-custom-preferences
Page caching of dynamic content must be enabled for the specific site.
To do so, in Business Manager, navigate to Administration > Sites > Manage Sites > Site Name - Cache and select “Enable Page Caching”.
How long a cache entry lives and whether the response is personalized, depends on the API and, if there are expansions available on the API, the selected expansions.
API name | Expansion | Cache time-to-live, seconds (Defaults) | Is personalized (Defaults) |
---|---|---|---|
Categories | N/A | 86400 | No |
Products | availability | 60 | No |
bundled_products | 86400 | No | |
images | 86400 | No | |
links | 86400 | No | |
options | 86400 | No | |
prices | 900 | Yes | |
promotions | 900 | Yes | |
recommendations | 86400 | No | |
set_products | 86400 | No | |
variations | 86400 | No | |
none | 86400 | No | |
Product Search | availability | 60 | No |
images | 900 | No | |
prices | 900 | Yes | |
represented_products | 900 | No | |
variations | 900 | No | |
none | 900 | No | |
Search Suggestions | N/A | 900 | No |
Promotions | N/A | 3600 | No |
Campaigns | N/A | 3600 | No |
SEO Url Mapping | N/A | 43200 | No |
Preferences (Site) | 300 | No | |
Preferences (Global) | 300 | No |
The lowest time-to-live of all the expansions decides how long the cache entry stays alive. If at least one of the requested expansions is marked as “personalized”, the whole response is considered to be personalized.
The cache hit rates are greatly impacted by the expansions you select for the product and product-search endpoints. For example, if a request to the product API includes the "availability" expansion, the cache entry is stored for only 60 seconds by default. If no expand parameter is specified, all expansions are considered selected.
Example 1
A request to /product/shopper-products/v1/organizations/{org-id}/products?ids=product1,product2
is made every 30 minutes. Since no expand parameter is specified, all expansions are applied, and the lowest time-to-live among them is for "availability", which is 60 seconds. Consequently, the cache hit rate is likely to remain zero because the cache entry expires before the next identical request is made.
Example 2
A request to /product/shopper-products/v1/organizations/{org-id}/products?ids=product1,product2&expand=images,links,options
is made every hour. The shortest time-to-live among the specified expansions is 86400 seconds (24 hours), so the cache hit rate is expected to be high.
Due to how short the cache entry live time is for certain expansions, we recommend you make sure only necessary expansions are included in the request. For example, unnecessarily including the “availability” expansion in requests to the Products and Product Search APIs reduces the cache hit rate drastically and negatively affect the overall performance of requests. If no expand parameter is specified, all expansions are considered selected.
When personalization is enabled for a resource, the following information becomes part of the cache key in addition to the URL string:
- The complete set of active promotions.
- The complete set of active product sorting rules.
- The complete set of applicable price books.
- The complete set of active ABTest Groups.
The cache stores different response variations in the cache and delivers the correct version to the API user based on this additional information.
Let’s think of what it means for two shoppers accessing the same product API (as in, the same URL). In this case, shopper A is eligible for promotion X, and shopper B is eligible for promotion Y. The same product (no change in URL) is cached twice. All shoppers with the promotion X are subsequently served the same respective cache entry, as are the shoppers with the promotion Y. Depending on the number of price books and promotions, this scenario can lead to a large increase in the number of cache entries, regardless of the price of the product.
Consider using personalized caching only when necessary. And only for well-sized groups of shoppers.
For a new request, the web-tier first checks for the existence of a cache entry for the given request. The cache key is calculated before any hook customization is invoked, and does not include any potential changes that will occur later within hooks. Therefore, changes in any personalization related resources, such as applicable price books or promotions, should be always applied using the Shopper Context API to ensure that the required price books and promotions are considered by the web-tier cache.
Changing applicable price books and promotions within hook logic leads to the final cache entry not matching the original key and thus in a decreased performance due to a lower cache hit rate. Use Shopper Context instead.
Similarly, potential updates of the response body (such as adding custom attributes) are not considered within the cache key. If two otherwise identical requests (URL and query string) are supposed to produce different responses solely due to conditional hook logic, the web-tier considers such requests as identical and will return the cached response. To ensure the correct behavior of the web-tier cache, it's recommended to append a custom query parameter to the URL.
Example:
The customization of responses via conditional code is only cached correctly in case the condition is given as part of the URL i.e. a custom query parameter. Do this only when necessary, because it can impact performance.
With B2C Commerce 24.8, you can set a time window, called the Validity Period, for the Shopper Products getProduct and getCategory endpoints and the Campaigns getCampaign endpoint. The validity is considered for server-side cache expiration in order to prevent serving stale content. The attributes that define the Validity Period are Valid From
and Valid To
. For other resource types, the default cache expiration times are applied.
The server-side cache expiration is adjusted to reflect date and time values of Valid From
and Valid To
attributes if those are defined and take effect prior to the default cache expiration. Otherwise, the default expiration is applied.
For requests that contain multiple resource identifiers, such as multiple SKUs, all Validity Periods are taken into consideration when calculating cache expiration. The earliest effective date determines the cache expiration of the response.
For example, a request using a single Product SKU is cached by default for 24 hours (no additional expansions; see table above). Assuming the Product has an assigned Valid To
time that is earlier than the default cache expiration, then the cache expiration is recalculated to reflect the shorter Valid To
time.
If you use a Valid From
time to configure a Product launch for a future date, an HTTP 404
response code is returned. The HTTP 404
response is also cached using a cache expiration that reflects the respective Valid From
value. When the cache expires at that time, the Product becomes viewable for shoppers in your storefront.
Script API provides options to control the cache settings programmatically.
The dw.system.Response#setExpires( milliseconds )
method of the Script API makes it possible to set an arbitrary cache expiration timestamp. Since the method accepts the timestamp in milliseconds, a sum of the current timestamp and desired “time-to-live” has to be passed as a parameter.
For instance, if a response for the Category API should be only cached for an hour instead of the day, the following custom code can be used:
The cache time-to-live has to be at least one second and cannot exceed 86,400 seconds.
The dw.system.Response#setVaryBy( String varyBy )
method of the Script API marks the response as personalized with the given variant identifier. Only price_promotion
is supported, and any other value has no effect.
By default, product calls with prices and promotions expansions, as well as product search calls with the prices expansion are personalized.
At the moment there is only one way to invalidate cache manually - which is to invalidate the entire site page cache.
In Business Manager, navigate to Administration > Sites > Manage Sites > Site Name - Cache, and select the Cache tab. In the “Cache Invalidation” section there is a button to invalidate the site page cache. Once the invalidation has been triggered, the entirety of the site page cache is cleared within 15 minutes, including the cache related to SCAPI responses.
Doing this also invalidates all existing pipeline cache, possibly resulting in a temporary decrease in performance.
With the new server-side caching in place, responses of cached endpoints always return the Cache-Control
header value: no-cache, no-store, must-revalidate
. This is necessary to ensure a uniform behavior of SCAPI and Script Controller APIs, especially in the case of personalization.
You can use the Web Adapter Cache Key Ignore by Query String
feature toggle to exclude query parameters from the cache key. This applies when you want to increase the cache hit rate, but only when the query parameter does NOT influence the response in any way. Because the specified query parameters affect the caching of Salesforce Commerce APIs and Controllers, use this feature toggle with caution.