Page Caching
The majority of the pages viewed on Altis will be cached to improve performance and delivery time to the user. It is necessary to take into account the page cache when developing - considerations are listed at the bottom of this page.
There are 2 levels of page caching:
- CDN caching, served from regional cache nodes
- PHP caching, served from PHP using Batcache
The CDN cache is the fastest cache, and has typical response times around 20ms. If a page cannot be served from the CDN cache, it may fall back to the Batcache cache. This is served from PHP on the application server, and has typical response times around 100-200ms.
All pages are cached by default, with the following exclusions:
- All
POST
requests are not cached - Any requests containing cookies with names that match the following patterns are not cached:
wordpress_*
wp-*
wp_*
comment_*
hm_*
altis_*
- Any requests with the
Authorization
HTTP header will not be cached. - Any response with the
Cache-Control: no-cache
HTTP header will not be cached. - Any response with no content is not cached.
- Any request to
xmlrpc.php
,wp-cron.php
orwp-app.php
are not cached. - Any request to
wp-includes/js*
are not cached.
Note: Page caching is disabled on local environments, and due to non-production environments requiring authentication, will likely not be active during testing and QA. See the configuration section below for testing instructions.
Cache Key Calculation
Each page is stored within cache storage as identified by a cache key. The cache key follows the pattern:
{method}:{protocol}:{host}:{path}:{query_params}:{cookies}
Query parameters can be customized to ignore certain query parameters which do not effect the page content.
Note: The cache key for the CDN cache is fixed, and query parameters can not be ignored within the CDN cache. The CDN cache key cannot be changed.
Note: Cookies are included in the cache key at the CDN level, but Batcache instructs the CDN not to cache pages with them set by default. Caching can be enabled (see below), but will still be unique per user.
Time-to-live and maximum age
Pages which can be cached have default time-to-live (TTL) values within the cache based on the response code:
- Success responses (
200
): 300 seconds (5 minutes) - Client errors (
400
, except404
): 10 seconds - Not found errors (
404
): 300 seconds (5 minutes) - Server errors (
5XX
): 300 seconds (5 minutes)
Time-to-live values should be balanced between achieving high cache hit rates and ensuring fresh content is served.
This can be adjusted by sending
a Cache-Control: max-age=x
HTTP header
within your response, which will override any defaults.
For example, to specify a lifetime of one hour for a specific page:
header( 'Cache-Control: max-age=' . HOUR_IN_SECONDS );
(Note that headers should be sent before any output occurs on the page.)
Developer Considerations
Pages that will be cached should not include references to any user-data in the request. This is because subsequent requests from other users will receive the same cached page.
This means headers such as User-Agent
, Referer
, or the client IP ($_SERVER['REMOTE_IP']
) will not be accurate for users
viewing the cached content. Content should not be varied based on these attributes;
use client-side personalization with Experience Blocks instead, which is
fully compatible with page caches.
Non-cacheable requests (such as logged-in users) can safely use these headers.
Note: The User-Agent header is set to a static value by Altis and cannot be used server-side for feature detection.
Customizations
The Batcache page cache can be customised via your composer.json
configuration.
The default configuration is:
{
"extra": {
"altis": {
"modules": {
"cloud": {
"page-cache": {
"ignored-query-string-params": [
"utm_campaign",
"utm_medium",
"utm_source",
"utm_content",
"utm_term",
"mc_cid",
"mc_eid",
"fbclid",
"_ga"
],
"unique-headers": [],
"unique-cookies": []
}
}
}
}
}
}
Note: These customizations do not apply to the CDN cache, only within Batcache.
Ignored Query String Parameters
Some query string parameters have no effect on the content or output of the page. You can improve your cache hit rate by adding these parameters to the ignore list, which will instruct Batcache to treat the different URLs as equivalent.
The page cache will filter these parameters out when generating the cache key as specified in the Cache Key Calculation section above, and will cause the cache key to be shared across more pages, improving your cache hit rate.
Note: Overriding this configuration option will completely replace the configuration, so if you want to retain any of the default parameters, ensure you repeat them in your custom configuration.
Headers
If you need to generate different content on the server side based on an HTTP request header, you can add those to
the unique-headers
property. This will add those header values into the key calculation.
For example in conjunction with geo-targeting you could add Cloudfront-Viewer-Country
to vary the generated
page cache key.
Note: This will not change the value on the CDN cache. Enterprise customers can contact Altis support to apply customisations at the CDN level.
Cookies
If the presence of a particular cookie means that the generated page should be unique you add the cookie name to
the unique-cookies
property. It's recommended to name the cookies accordingly to a current exclusion pattern if you want to access
them via PHP e.g. wp_*
.
By default, requests beginning with wp
, wordpress
, or comment_author
skip the cache, as Batcache generates a no-cache
header. This behaviour can be overridden by explicitly setting the Cache-Control
header to force caching on the CDN (note:
prefixed cookies form part of the CDN cache key, and so are unique for each cookie value).
Note: This will not change the value on the CDN cache. Enterprise customers can contact Altis support to apply customisations at the CDN level.
Unique keys
If the above configurations don't meet your needs you can add your own cache vary keys directly in PHP. The recommended place to do
this is in a file under the .config/
directory in a file included via .config/load.php
to ensure it runs early enough.
The following example will make the cache key for the page unique to the current codebase commit hash.
global $batcache;
$batcache['unique']['revision'] = Altis\get_environment_codebase_revision();
Cache Invalidation
Caches are automatically invalidated when their time-to-live expires.
The CDN cache can be manually purged through a function call. This should be used sparingly, as it will negatively affect cache hit rates, and incurs additional stress on the CDN system. This functionality is monitored, and excessive use may be considered a violation of your terms of service.
It is not currently possible to clear Batcache cache values manually. As Batcache cache values are stored within the object cache, the object cache can be cleared if Batcache needs to be cleared, however this also must be used sparingly.
Debugging
Altis sends response headers indicating the cache status, allowing you to debug the cache behaviour.
Since Altis operates a layered cache system, the CDN cache status (X-Cache
) supersedes the Batcache status (X-Batcache
).
X-Cache Header
Describes the status of the edge page cache from the CDN:
Hit from Cloudfront
- the page was served from the regional edge cache by the CDN.Miss from Cloudfront
- the page was not served from the CDN cache, but may have been added to the page cache for subsequent visits.
Additionally, the x-amz-cf-pop
header indicates the CloudFront point-of-presence (POP) being accessed. The first three characters
indicate which CloudFront edge the response was served from.
X-Batcache Header
Describes the status of the origin page cache:
HIT
- The page was served from the Batcache page cache.MISS
- The page was not served from the cache, but has been added to the page cache for subsequent visits.BYPASS
- The page was not used, due to exclusion rules such as logged in users, request type (detailed above).
Note: The X-Batcache
header may indicate a MISS
on pages with X-Cache: Hit from Cloudfront
. This indicates the page was
served from the CDN cache, and the original request which was cached by the CDN also missed the Batcache cache.
The specific reason for the BYPASS
in cache is described via the X-Batcache-Reason
HTTP header, and can be one of the following
values:
Set-Cookie
- The response set a cookie that excludes the page from the cache.Auth Request
- The request specified theAuthorization
HTTP header which excludes the page from the cache.Cookies
- The request contained cookies matching cookie exclusion rules.Canceled
- The backend response made a call tobatcache_cancel()
to force the response not to be cached.No content
- The response contained no content,Bad status code
- The response returned a 5XX error code.Filename
- The request was for an excluded filename.JS Generator
- The request was for awp-includes/js*
path which is excluded from the cache.
Configuration
PHP page caching can be toggled using the Altis config. By default Batcache is active for cloud environments but not on local environments.
This can be toggled by changing the following setting to true
or false
:
{
"extra": {
"altis": {
"modules": {
"cloud": {
"batcache": false
}
}
}
}
}
For developing cache customizations locally, you may wish to enable Batcache for local environments:
{
"extra": {
"altis": {
"environments": {
"local": {
"modules": {
"cloud": {
"batcache": true
}
}
}
}
}
}
}