Content Delivery Networks (CDNs) are commonly used with AEM to improve website performance by and from edge locations closer to users. However, when AEM content changes it can lead to in the . Manual cache invalidation is complex and error-prone. caching serving content outdated copies CDN cache Though CDNs improved performance, our authors’ new changes weren’t reflected until caches expired. post-publish did not scale. Clearing the cache manually I could not find an existing out-of-the-box solution for this problem. So I developed an that and selective cache based on . open-source AEM library listens to publishing events automatically triggers invalidation configurable rules The library AEM replication events or resource changes and then runs to invalidate cached CDN content related to the published updates. allow various CDNs while enable customization. reacts to asynchronous background jobs Flexible APIs integration with extension points The Problem CDNs cache website content like pages, images, and JS/CSS assets. This avoids repeatedly serving from the AEM publish tier which . The CDN only re-fetches assets when they from the after a . static content improves response times expire cache TTL (Time to Live) However, updated AEM content can get lingering in the CDN after publishing. Some examples: outdated copies a new content page is not immediately to users. The older version remains cached. Publishing visible a product image in DAM does not show until the CDN cache expires. Updating Depending on the business context, any of these situations can be a really that needs to be addressed urgently. But sadly, on every publish is and : sensitive issue clearing the cache manually operationally complex time-consuming Identifying related URLs is manual and repetitive Tedious cache tagging schemes to coordinate flushing An automated solution is needed… one that selectively and intelligently invalidates cache only for published updates. Automated Cache Invalidation Library “Automatic CDN Cache Invalidator for AEM” listens to publish events and resource changes, then triggers background cache invalidation per configurable rules. Flexible APIs allow integration with various CDNs. https://github.com/realgpp/aem-cdn-cache-invalidator?embedable=true Key Capabilities : Reacts to AEM replication events for publishing updates Automatic triggering Invalidates cache only for specific published paths rather than mass flush Selective invalidation: Uses queue-based jobs framework to offload CDN calls Async processing: Flush cache by URL, tag or custom criteria Configurable rules: Detailed logging for tracking Logs: Akamai Purge API is integrated Akamai support built-in: Easily extendable for other CDNs via APIs Flexible CDN integrations: Hooks to personalize behavior Extension APIs: It solves manual cache management challenges allowing authors to focus on content while optimizing end-user experience. Let’s walk through the flow… How it Works The application has configurable OSGi services and listeners for cache invalidation triggered by AEM events. : Replication or resource change events signify content updates. Event listening An OSGi listener consumes events filtering to specific trees. It creates asynchronous jobs with updated paths. Selective listener: A separate job thread processes paths to extract cache-related metadata like URLs, tags etc. Background job: The job makes the API call to invalidate the cache for the computed metadata. CDN API call: The CDN receives the API request and flushes related cached content. Cache flush: The async approach avoids publish request performance impact. The CDN calls happen out-of-band without blocking AEM. The entire flow is configurable via OSGi including supported events, cache criteria, URLs, or logic. Out-of-the-box integrations make it easy to get started while extension points allow customization. Let’s explore common configuration options… Purging content with Akamai API The project includes reusable services, listeners, and jobs supporting caching scenarios like: Invalidating pages or assets by URL Website sections by or tag code The following are the Akamai Purge APIs supported out of the box: and by Tag invalidation deletion and by CP Code invalidation deletion and by URL invalidation deletion The following block, which you can find in the ui.config.example maven module, shows how to configure the Akamai service that comes with the library. // file com.baglio.autocdninvalidator.core.service.impl.AkamaiInvalidationServiceImpl.cfg.json { "isEnabled": true, "configurationID": "cdn-akamai", "hostname": "localhost:8443", "getAkamaiClientToken": "placeholder_akamai_client_token", "getAkamaiAccessToken": "placeholder_akamai_access_token", "getAkamaiClientSecret": "placeholder_akamai_client_secret", "httpClientConfigurationID": "http-client-akamai", "purgeType": "invalidate" } This service lets you choose how to purge content from the CDN: you can either invalidate or delete it. As you can see, you need to replace placeholders with your Akamai values. You also need a dedicated HTTP Client Configuration to work with the Akamai APIs. After that, your service can be used by other sling jobs that handle content-change events. Now let’s explore other configuration options that let you customize the library without coding… Configuration Areas The library offers a variety of configuration options to customize its functionality without code customizations. You can adjust these settings to suit your specific needs and preferences. I want to keep this introduction brief and engaging but don’t worry if you have questions about the details. You can find more information in the README.md file of the project or in the Javadoc comments if you like to explore the code. Key aspects to configure are: Replication topics or resource change events that trigger the invalidation jobs. Observed events: // file com.baglio.autocdninvalidator.core.listeners.ReplicationEventListener-website-generic.cfg.json { "isEnabled": true, "resource.paths": [ "/content/we-retail", "/content/wknd" ], "job.topic": "com/baglio/autocdninvalidator/akamai/generic", "filter.regex": "^/content/(we-retail|wknd)(?!.*products)(?!.*adventures).*$" } // file com.baglio.autocdninvalidator.core.listeners.DynamicResourceChangeListener-website-generic.cfg.json { "isEnabled": false, "resource.change.types": [ "CHANGED" ], "resource.paths": [ "/content/we-retail", "/content/wknd" ], "job.topic": "com/baglio/autocdninvalidator/akamai/generic", "filter.regex": "^/content/(we-retail|wknd)(?!.*products)(?!.*adventures).*$" } API credentials and settings for your provider. CDN credentials: // file com.baglio.autocdninvalidator.core.service.impl.AkamaiInvalidationServiceImpl.cfg.json { "isEnabled": true, "configurationID": "cdn-akamai", "getAkamaiClientToken": "placeholder_akamai_client_token", "hostname": "localhost:8443", "getAkamaiAccessToken": "placeholder_akamai_access_token", "getAkamaiClientSecret": "placeholder_akamai_client_secret", "httpClientConfigurationID": "http-client-akamai" } Filtering rules and cache flush criteria for each job consumer. Invalidation rules: // file com.baglio.autocdninvalidator.core.jobs.EditorialAssetInvalidationJobConsumer.cfg.json { "isEnabled": true, "job.topics": [ "com/baglio/autocdninvalidator/akamai/generic" ], "cdnConfigurationID": "cdn-akamai", "invalidation.type": "tag", "tagCodeMappings": [ "/content/we-retail/(..)(/.*)*=tag-dev-$1", "/content/we-retail/(..)/.*/experience/.*=tag-dev-$1-experience", "/content/wknd/(..)(/.*)*=tag-dev-$1", "/content/wknd/(..)/.*/adventures/.*=tag-dev-$1-adventures" ] } Throttling and parallelization configs for each job topic. Please have a look at the section Custom Job Queue Configuration of project README file. Job topic tuning: These configurations determine how the library responds to AEM events, how many cache jobs run concurrently, and how the service communicates with your CDN provider to purge the cache. Now that we have learned the basics, let’s move on to the fun part where we show you how to make the invalidation work on the AEM instance… Enabling Akamai CDN Integration If you want to use this library right away, you don’t need to write any code. Just follow these simple steps: : Install the ui.config.example module or create the manually. The ui.config.example module is a sample configuration that provides a working example for . You can install it from the package manager or create the OSGi config manually through the web console. Step 1 OSGi config Akamai integration : Enter your Akamai and in the . You must provide your Akamai hostname, client token, access token, and client secret in the AkamaiInvalidationServiceImpl config file. You can find these values in your Akamai portal. Step 2 credentials settings AkamaiInvalidationServiceImpl config file : Choose to AEM events on Author or Publish.Depending on your setup, you can choose to listen for AEM events on Author or Publish. If you choose Author, the module will detect and the accordingly. If you choose Publish, the module will detect and the accordingly. Step 3 listen for publish events invalidate cache content updates purge cache Now let’s walk through adding support for a new custom CDN provider… Implementing a Custom CDN Provider Now that we’ve explored utilizing the library without coding, what if you encounter the need for a CDN provider that isn’t currently supported? The library is designed for to support new CDN providers. You can easily extend it by following these steps: extension Create a Java class the . This interface defines the methods for the . implementing CdnInvalidationService interface purging CDN cache Implement the logic for your CDN’s in your implementation class. calling purge API Create an for your class with the necessary and property values. Make sure to give it a so that it can be identified by the invalidation job. OSGi configuration credentials unique configuration ID Use the configuration ID mentioned above when you create configurations. invalidation job The library provides the invalidation logic when using the built-in Akamai integration. If you need to the or , the class exposes you can without having to reimplement the full Akamai handling. flexibility to customize tweak preprocessing postprocessing AbstractInvalidationJob hook methods override With the procedure shown in the above image, you get the benefits of leveraging the existing Akamai capabilities while adapting things like: - The and methods allow transforming the content paths and invalidation values before and after generating them. preprocessInvalidationValues postprocessInvalidationValues - The and methods allow updating the public URLs before and after resolving them. preprocessPublicUrls postprocessPublicUrls - The and methods enable logic before and after making the CDN purge call. beforeInvalidation afterInvalidation By selectively overriding these hooks, you can adapt the data and flows to your needs while reusing the bulk of the Akamai integration code. This makes the library very extensible without having to start from scratch. Wrap Up And that’s a wrap! We’ve covered everything from to with this CDN invalidator library. I hope you found it an interesting read! out-of-the-box setup fully custom integrations Did any part leave you scratching your head? Or maybe this library has already helped you invalidate caches more easily? Either way, I’d love to hear your thoughts! Let me know what worked, what didn’t, or what other guides would help improve your CDN workflows. Even better — I welcome if you have , tweaks, or new snippets that can this library and tutorial! pull requests code changes enhance I greatly appreciate you taking the time to provide and . Your will help this project and craft content that empowers fellow developers to their . feedback contributions real-world experiences evolve master CDN footprints Also published . here