Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

HTTP caching and reverse proxies

HTTP-level caching in Exponential for developers who know Symfony's HttpCache, Varnish setups, Laravel response caching or Django's cache middleware - page headers for anonymous visitors from settings, the role-aware…

Download as PDF

Address: https://doc.exponential.earth/learninminutes/exphelp/viewer/help/web-framework-developers/http-caching-and-reverse-proxies.md

On this page

HTTP caching and reverse proxies

This page is for developers who set Cache-Control from a controller, put Varnish in front, or use a framework's HTTP cache. In Exponential, page headers are settings, and there are two built-in page caches that sit in front of the kernel. Nothing is cached at the HTTP level until you switch it on.

Contents

  1. What is sent by default
  2. Headers for anonymous visitors
  3. The role-aware HTTP cache
  4. The Velocity response cache
  5. Behind a proxy or CDN
  6. Never cache
  7. Compared with other frameworks

What is sent by default

Pages: Cache-Control: no-cache, must-revalidate, an expired Expires and Pragma: no-cache. So no browser, proxy or CDN keeps a page until you decide otherwise (HTTP caching for anonymous visitors).

Headers for anonymous visitors

# settings/override/site.ini.append.php
[HTTPHeaderSettings]
CustomHeader=enabled
OnlyForAnonymous=enabled
OnlyForContent=enabled

HeaderList[]
HeaderList[]=Cache-Control
HeaderList[]=Expires

Cache-Control[]
Cache-Control[/]=public, max-age=60
Expires[]
Expires[/]=60

OnlyForAnonymous is what makes this safe: a signed-in user always receives the no-cache headers. The keys are paths, so different parts of the tree can get different lifetimes. The trade is staleness: an anonymous visitor may see a page up to max-age seconds old after an edit.

The role-aware HTTP cache

The kernel's HTTP cache (settings/httpcache.ini, [HttpCacheSettings] Enabled=disabled shipped) stores rendered content views keyed by scheme, host, siteaccess, path and the visitor's permission context: one copy for anonymous visitors, one per set of roles and role limitations, and a private copy only where a content/read policy depends on the user. The next request is answered before the kernel starts: by an early exit included from config.php under Apache, PHP-FPM or FrankenPHP, and by the server process itself under Velocity. The X-Exp-Cache header says HIT, STALE, MISS or BYPASS with a reason. The visitor's own form token is put back into the stored page on every hit (The role-aware HTTP cache).

This is unusual: most framework HTTP caches only serve anonymous traffic. Here signed-in members share cached pages safely because the key is their permission context.

The Velocity response cache

Velocity can answer repeat requests for public pages inside the server process, before a worker is chosen: conditional requests (304), ETag, Age, stale-while-revalidate and invalidation, like a small reverse proxy built into the server. It is off until a setting enables it (Velocity response cache). Clear it last in a deploy: ./console exp:velocity cache clear --apply.

Behind a proxy or CDN

  • List the proxy's addresses in site.ini [HTTPHeaderSettings] TrustedProxies[], so forwarded scheme and host are believed only from them (Trusted proxies, Behind a reverse proxy).
  • Let the CDN cache only what the site marks as cacheable; signed-in sessions carry a cookie the CDN must pass through.
  • For a purging proxy in front, httpcache.ini [HttpCacheSettings] TagHeader can send the purge tags of each page (its nodes, objects and layouts) in a header such as xkey (Varnish xkey vmod), Surrogate-Key (Fastly) or Cache-Tag (Cloudflare); it is disabled by default because the tags name internal ids. Sending the purge request to the proxy on publish is yours to add, for example in a content/cache listener (Events and listeners).

Never cache

From HTTP caching and CDNs: pages for signed-in users in a shared cache, baskets, checkout, account pages, forms with a form token (the token is per session), and the administration.

Compared with other frameworks

FrameworkConceptExponential
SymfonyHttpCache reverse proxy, #[Cache], ESIsettings-driven headers, the role-aware HTTP cache, the Velocity response cache; no ESI
Laravelresponse cache packages, Cache-Control middlewarethe same settings and caches
Djangocache_page, UpdateCacheMiddlewarethe same
Railsexpires_in, fresh_whenheaders per path in settings

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x