Day 6 of 40
Dispatcher
The caching and security layer in front of publish
By the end of today you should be able to
- Explain the three jobs the Dispatcher does and why each matters
- Describe how the Dispatcher decides whether a request is cacheable
- Explain cache invalidation via .stat files and statfileslevel
- 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..jsonselectors on arbitrary content — the default Sling GET servlet will happily serialise a subtree, so/content.infinity.jsoncan 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.
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-cachestyle 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
.statat the root. Publishing anything invalidates the whole cache. Simple, safe, and terrible for hit rate on a big site. - Higher value —
.statfiles 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,/rulesfor what to cache,/invalidatefor what flushing affects, andstatfileslevel.
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.
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.
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.