Configuring Varnish for Adobe Experience Manager

Tags: aem (1) adobe experience manager (1) vcl (20)

Adobe Experience Manager (AEM) is an enterprise web content management system that facilitates organizing, managing, and delivering creative assets. It has ready-made templates that users can use to create content and store them securely in the cloud.

Primarily, Adobe recommends using the Adobe Dispatcher for caching pages. But, as well you may know, it is not flexible enough for the cache invalidation techniques needed today.

Adobe Dispatcher

It is relatively straightforward. It has built-in rules for invalidation. These specified rules are not flexible enough.

Dispatcher limitations

  • Cached documents as delivered in the AEM instance
  • Does not cache HTTP headers (which provide info on handling that content)
  • Holds onto the document
  • Does not hold onto the accompanying HTTP response

This is where Varnish Enterprise can help in managing the complex rules needed for your site’s cache invalidation.

Replacing Adobe Dispatcher with Varnish

  1. The first rule of replacing Adobe Dispatcher with Varnish is to ensure that the VCL configuration file mimics the behavior of the dispatcher (an Apache module making use of CQ-handle headers to invalidate).

  2. Any more site specific knowledge of the website layout can be used to limit the trees of invalidation more aggressively. Have a look at the following blog post: AEM - Cache Invalidation Part 2

  3. Setup preference for bans:

  • You can have Apache, Varnish and AEM on the same machine
  • You can have them on different machines and use the Varnish built-in SSL/TLS capabilities for handling both the request from the client and the backend.

VCL example

An example of excluding backend responses from the cache based on headers like:

  • Dispatcher
  • Cache-Control
  • Pragma
vcl 4.1;

backend default {
    .host = "localhost";
    .port = "8080";

sub vcl_recv {
    if (req.url ~ "\?" || req.url ~ "\/cug_") {

sub vcl_backend_response {
    if (beresp.http.Dispatcher ~ "no-cache"
     || beresp.http.cache-control ~ "(no-cache|private)"
     || beresp.http.pragma ~ "no-cache") {
        set beresp.ttl = 20s;
        set beresp.uncacheable = true;
    else {
        set beresp.ttl = 4w;