AEM in 40 Days
CalendarPhase 1 · Foundations

Day 6 of 40

Dispatcher

The caching and security layer in front of publish

~40 min read2 videos4 source pages

By the end of today you should be able to

  1. Explain the three jobs the Dispatcher does and why each matters
  2. Describe how the Dispatcher decides whether a request is cacheable
  3. Explain cache invalidation via .stat files and statfileslevel
  4. Read a dispatcher farm configuration and identify the filter, cache and rules sections

Three jobs, not one

People call the Dispatcher "the AEM cache", which undersells it. It is a module for Apache HTTP Server sitting in front of publish, and it does three things:

  • Caching — stores rendered responses as files on disk and serves them without touching AEM.
  • Security filtering — rejects requests that should never reach AEM at all. This is a genuine security boundary, not an optimisation.
  • Load balancing — distributes requests across multiple publish instances (less relevant on Cloud Service, where Adobe handles it).

On AEM as a Cloud Service the Dispatcher still exists and you still configure it — it lives in the dispatcher module of your archetype project and is deployed by the pipeline. Adobe's CDN sits in front of it.

The security half

A default-deny filter section is the single most important thing in the configuration. Without it, the public internet can reach paths that leak far more than you intend:

  • /system/console — the Felix console. Catastrophic if exposed.
  • /crx/de — CRXDE Lite, a full repository browser.
  • .json selectors on arbitrary content — the default Sling GET servlet will happily serialise a subtree, so /content.infinity.json can dump a great deal of content.
  • Query-building endpoints like /bin/querybuilder.json.

The convention is: deny everything, then allow narrowly — specific paths, specific extensions, specific selectors, specific methods.

Test this deliberately

Requesting /content/wknd/us/en.infinity.json through the Dispatcher should fail. If it returns content, your filters are too permissive. This is a standard finding in AEM security reviews.

What gets cached

The Dispatcher caches a response only if all of the following hold — and it is worth memorising, because it explains most "why isn't my page cached" questions:

  • The request is a GET (or HEAD), not POST.
  • There is no query string — this is why selectors beat query parameters.
  • There is no authorisation header / no auth-sensitive request, unless you explicitly enable permission-sensitive caching.
  • The response has no no-cache style headers, and the extension is in the allowed list.

Cached responses are stored as real files under the docroot, mirroring the URL path. A request for /content/wknd/us/en/home.html becomes a file at <docroot>/content/wknd/us/en/home.html. You can literally look at the cache on disk, which makes debugging refreshingly concrete.

Invalidation and .stat files

When content is published, AEM sends a flush request to the Dispatcher. Rather than deleting individual files, the Dispatcher touches a .stat file. Any cached file older than the nearest relevant .stat file is considered stale and re-fetched on the next request.

statfileslevel controls how deep .stat files are placed. It is a direct trade-off:

  • Low value (0) — one .stat at the root. Publishing anything invalidates the whole cache. Simple, safe, and terrible for hit rate on a big site.
  • Higher value.stat files deeper in the tree, so publishing one section invalidates only that section. Better hit rates, more configuration care.

Reading a farm file

Dispatcher configuration is a set of farms, each with recognisable sections:

  • /clientheaders — which request headers get forwarded to AEM.
  • /virtualhosts — which hostnames this farm answers for.
  • /renders — the AEM publish instances behind it.
  • /filter — the allow/deny rules. The security half.
  • /cache — docroot, /rules for what to cache, /invalidate for what flushing affects, and statfileslevel.

On Cloud Service the structure is prescribed and validated: your project holds dispatcher/src/conf.d and conf.dispatcher.d, and the pipeline runs a validator that rejects configurations that stray outside the supported shape.

Today's takeaway

Cache, filter, balance. Deny by default and allow narrowly; cache only clean GETs; invalidate with .stat files and tune depth with statfileslevel.

Watch

Adobe's own videos for this topic. They load only when you press play.

Introduction to Dispatcher
Configuring Dispatcher - Moving to AEM CS

Read on Experience League

The primary sources these notes are drawn from.

Your notes

Saved automatically to this browser.

Check yourself

11 questions on today's material. 80% to pass.

Take the quiz