Dec 15, 2023 | technology

AEM In-Depth: Setting up effective caching rules for the Cloud

by Steven Longbons4 min read | Share:

You will need to carefully consider your caching rules in order to get the best performance from your AEM as a Cloud Service installation.

AEM as a Cloud service comes automatically bundled with Adobe's mandatory CDN, Fastly. However, unless you specify the correct caching rules in your custom Dispatcher vhost you will most likely have performance issues when the site encounters any significant traffic.

Let's take a step back. You have set up a brand new AEM site on AEM as a Cloud service using the latest Cloud Archetype code. You've created all of your custom code and completed design UAT and functional testing of your new site. And you have worked with your agency partner and/or with Adobe's own launch services consultants to prepare for your go-live. One of essential steps prior to go-live is a performance load test. You carefully set up the first test for a moderate load and as soon as the test starts your site starts throwing 500 errors.

Of course, Adobe's cloud service will auto-scale and add additional nodes when it detects heavy loads, but the scaling takes time - several minutes to add meaningful capacity to your cluster. That's why Adobe requires Fastly for your AEM site. Fastly is supposed handle any spikes by serving all of your static assets and cached pages from the edge so that the Cloud infrastructure has time to scale under heavy load. (You can also add your own CDN, such as Cloudflare in front of Fastly, but that's another blog post). However, the AEM archetype does not include the required caching rules.

To fix the problem you will need to update your custom Dispatcher code to optimize the performance. When we first started working with Adobe's cloud service several years ago, the cache code was not well documented, so it required some trial and error. Thankfully, Adobe has dramatically improved the documentation. But to save you some time I am including some of our preferred cached rules below.

All of these rules can be added to your custom vhosts file located in the Dispatcher folder here: "dispatcher/src/conf.d/available_vhosts/yoursitename.vhost".

Cache mutable resources for 24 hours

# Theme Sources via Clientlib: cache mutable resources for 24h on CDN and background refresh to avoid MISS
<LocationMatch "^/etc\.clientlibs/.*\.(?i:json|png|gif|jpe?g|svg)$">
    Header set Cache-Control "max-age=7200,s-maxage=86400,stale-while-revalidate=43200,stale-if-error=43200,public"
</LocationMatch>

Cache immutable resources for 30 days

# Theme Sources via Clientlib: long-term caching (30 days) for immutable URLs, background refresh to avoid MISS
<LocationMatch "^/etc\.clientlibs/.*\.(?i:js|css|ttf|woff2)$">
    Header set Cache-Control "max-age=2592000,stale-while-revalidate=43200,stale-if-error=43200,public,immutable"
</LocationMatch>

Cache core component images for 30 days

# Core Component Image Component: long-term caching (30 days) for immutable URLs, background refresh to avoid MISS
<LocationMatch "\.coreimg\..*\.(?i:jpe?g|png|gif|svg)$">
    Header set Cache-Control "max-age=2592000,stale-while-revalidate=43200,stale-if-error=43200,public,immutable"
</LocationMatch>

Cache regular pages for 10 minutes

# HTML pages: CDN cache for 10min with background refresh to avoid MISS, also incl. html requests with query parameter
<LocationMatch "\.html$">
    Header unset Cache-Control
    Header always set Cache-Control "max-age=120,s-maxage=600,stale-while-revalidate=43200,stale-if-error=43200"
    Header always set Cache-Control "no-cache" "expr=resp('Location') =~ m#\?not_found#"
</LocationMatch>

Cache images and videos loaded from the DAM for 4 hours

# Images/Video from DAM: cache mutable resources for 4h on CDN and background refresh to avoid MISS
<LocationMatch "^/content/dam/.*\.(?i:jpe?g|gif|ico|mov|png|svg)$">
    Header set Cache-Control "max-age=7200,s-maxage=14400,stale-while-revalidate=43200,stale-if-error=43200"
</LocationMatch>

Cache GraphQL API routes for 10 minutes

# GraphQL API: CDN cache for 10min with background refresh to avoid MISS
<LocationMatch "^/graphql">
    Header unset Cache-Control
    Header always set Cache-Control "max-age=120,s-maxage=600,stale-while-revalidate=43200,stale-if-error=43200"
</LocationMatch>

Cache Tags json for 1 hour

# Tags JSON - cache for 1h in browser and CDN
<LocationMatch "^/bin/tags.json">
    Header set Cache-Control "max-age=3600,s-maxage=3600"
</LocationMatch>

Applying all of the cache rules above to your AEM Dispatcher vhost should provide a good baseline for all typical public website use cases. You can then add additional rules or tweak these baseline rules to get the required performance and/or authoring requirements. Keep in mind that as of this writing, Adobe does not give its customers an easy way to "break" the Fastly cache manually for any asset. Hopefully Adobe will add this feature in the future. Happy caching!

Abstract

AEM as a Cloud service comes automatically bundled with Adobe's mandatory CDN, which is Fastly. However, unless you specify the correct caching rules in your custom Dispatcher vhost you will most likely have performance issues when the site encounters any significant traffic. This blog post details the most essential cache rules for any AEM site.