Response Caching

Types of Cache

Response Cache

Response Cache (RC) is a file system based cache. It is used in development and production environments for caching HTML and PDF responses, as well as some images. This is a public cache and does not cache user-specific responses.

Response cache is enabled in production and in development environments. However, caching of some resources is handled differently in production and in development environments (see Resource Types).

There are two handlers in response cache - one for images, and another one for pages (HTML and PDF responses). When DXP2 starts processing HTTP request, it checks both handlers if they have the requested resource in their cache. If resource has been found in cache, and it is not stale (has not expired) it may be served to the client, if it passes all the other release conditions of the handler (see the next section).

Images Handler

Cached images are stored in the .images subdirectory of the site directory and have a tree-like structure which corresponds to the public URL of the underlying image, or it's transformed variant.

.images
└── files
    └── images
        ├── components
        │   └── main-logo.jpg
        │       ├── main-logo.jpg
        │       ├── main-logo.jpg?h=500&s=exact&w=500
        │       └── main-logo.jpg?h=600&s=exact&w=600
        └── pages
            ├── home
            │   ├── step-1.jpg
            │   │   └── step-1.jpg
            │   ├── step-2.jpg
            │   │   └── step-2.jpg

Caching conditions

In production environments images will be cached only if all the following conditions are met:

In development environments all images will be cached in response cache.

Cache release conditions

Cached images will be released from cache if the following release conditions are met:

Dynamic Response Cache (pages)

HTML and PDF responses are stored in the site directory under .cache/response subdirectory and have a tree-like structure which corresponds to the public URL of the underlying page. Each hostname has its own version of cache, as the hostnames may be attributed to different environments and potentially different templates.

response
└── corednacom.coredna.site
    ├── services
    │   └── saas-platform
    │       └── _content-management-system
    ├── _contact-us
    ├── _about-us
    └── __root

Caching conditions

Dynamic resources will be cached only if all the following conditions are met:

Cache release conditions

Cached images will be released from cache and served to the clients, if the following release conditions are met:

Bypassing Response Cache

The no-cache Requests. Hard Reload

Response cache respects no-cache requests. If the client (browser) sends Cache-Control: no-cache header, such request will bypass response cache and a fresh copy of the requested resource will be served. Most browsers send no-cache requests when doing hard reload. Hard reload is usually done by holding Shift (or Ctrl+Shift) while refreshing the page, or disabling cache in Developer Tools, or right-clicking on the "Refresh" button and selecting "Hard Reload".

This enables an easy way to bypass response cache, which is handy, especially in development mode when it is important to see the actual.

Authenticated Users

Response cache is a public cache and does not store content for authenticated users. To effectively bypass response cache for dynamic content (i.e. pages), it is sufficient to login as some user. Authenticates users bypass response cache on content URLs, but not the images.

Response Cache HTTP Headers

Hit or Miss

Response Cache sends X-Cache-Status HTTP header to indicate if the request had hit response cache and a cached version of resource was served.

The possible values are:

X-Cache-Status: miss, no-store

Request missed cache and the current response will not be stored in the response cache due to failing some caching condition (e.g. user is logged in).

X-Cache-Status: miss, store

Request missed cache, but the current response will be stored in the response cache and in the future may be served from cache. In such situation Cache-Control header will indicate TTL in the max-age parameter.

X-Cache-Status: hit

Request hit response cache and HTTP response was served from response cache. HTTP response headers will also include Cache-Control and the Age headers, indicating the TTL and the age of the resource. For example:

X-Cache-Status: hit
Cache-Control: private, max-age: 3600
Age: 1200

The headers above indicate a cache hit. The "freshness" of resource is set to 3600 seconds (1 hour) and the current age of the cached resource is 1200 seconds (20 minutes). In 40 minutes times this resource will become stale and will be revalidated.

Varying Parameters in the URL and Variants

By default, the requested resource is matched only by the path in the URL, disregarding a query string. The following two requests will hit the same key in response cache: /my-page and /my-page?foo=bar. This improves cache efficiency when request parameters are only used in Javascript (e.g. to track marketing campaigns). However, if request parameter affects the content rendered by a template, this parameter becomes a vary parameter, and it's value is included in the key used for caching. There may be more than one vary parameter for a request - in this case a separate variant of response is created for each combination of vary parameters.

A parameter is automatically considered a vary parameter when it is accessed in a template which is used to render response: {$_request->getParameter('foo')}. It is also possible to explicitly specify a list of vary parameters using the $_response helper:

{$_response->setCacheVaryParameters(['foo','color','size'])}

This is particularly useful when some parameters are used within a condition which uses another parameter:

{if $_request->getParameter('foo')=='bar'}
  {$color = $_request->getParameter('color')}
{/if}

It is important that the cache is aware of all request parameters used to process the request and render response because all vary parameters are recorded in the cache file (see Cache File Structure). When request is processed by response cache handler, at first, the cache record without parameters is loaded. Then vary parameters are read from that base record and any parameters provided with the requests are matched against vary parameters and the variant record is loaded from cache.

For more information about controlling cache from the templates see Cache Controls in Templates.

Cacheable Response Headers

The following response headers will be cached:

Cache file structure

Cache file stores cached content, headers, vary parameters and cache expiry information in a JSON structure.

{
    "headers": {
        "Content-Type": "text/html; charset=UTF-8",
        "Cache-Control": "max-age=604800, private"
    },
    "varyParams": [],
    "content": "PGgxPkZvb3RlcjogMTg6MTI6MjM8L2gxPg==",
    "expiry": {
        "date": "2022-01-15 07:12:23.000000",
        "timezone_type": 1,
        "timezone": "+00:00"
    },
    "created": {
        "date": "2022-01-08 07:12:23.094162",
        "timezone_type": 3,
        "timezone": "UTC"
    }
}

CDN Cache

CDN cache is a geographically distributed cache which allows serving HTTP responses from the most proximate geographical location to the user. There are 45 points of presence (POPs) around the world. Each POP has its own cache storage. The same request may hit cache is one location, but miss in another.

In development mode CDN caching is disabled. In production mode CDN caching is enabled for all virtual files (including transformed images) and static files, and it can also be enabled for dynamic content in the DXP (see Resource Types).

CDN Headers

When CDN cache is enabled, the response cache will send the appropriate headers to the CDN to indicate that resource is public and cacheable.

Also, it will send X-CDN-Key response header with a unique CDN key which identifies the site, the environment and the class of the resource. Here is an example of the value of such header:

corednacom.1.2.d
│          │ │ └─ indicates "dynamic" resource
│          │ └─ Environemnt ID
│          └─ Site ID
└─ Config Instance name     

Resource Types

There are three main resource classes: dynamic content, virtual files and static files. Each class has different caching rules and supports different types of caching.

Dynamic Content

Dynamic content is the content served by the CMS as HTML, PDF or JSON responses. JSON responses are currently not cached at all. HTML and PDF responses are cached with Response Cache. The TTL setting is controlled in the DXP (System -> Global Settings), and by default it is 1 week. It is possible to enable CDN caching for dynamic resources using a switch in the DXP. If CDN cache is enabled, the same TTL settings will be applied to the CDN cache. Dynamic cache can be also controlled in the templates (see the corresponding section).

It is important to mention that due to the limitations of Stackpath CDN, caching of dynamic resources is not compatible with WAF, so WAF must be disabled for the sites which cache pages on the CDN.

Also, it is important to ensure that the "Lifetime" setting in Stackpath is set to "Origin Controlled", otherwise it will not be possible to control TTL value from the DXP.

Virtual Files (including images)

All files managed via File Manager module are the virtual files. All virtual files are cached on CDN. The TTL setting is controlled in the DXP (System -> Global Settings). The default TTL for virtual files is 6 weeks. Normally, the virtual files are not cached with file system based Response Cache, given the files are delivered from the file system anyway. However, there are two exceptions:

Static Files

Static files are the files committed into the website's repository. They are served from the local file system in both, production and development environments, and do not need file based caching. In production environments the static files are cached on CDN with the TTL of 365 days.

A Summary Table with Resource Classes and How they are Cached

Virtual File Type Production Development CDN Key Invalidated By
HTML response RC, CDN* RC {config}.{site_id}.{environment_id}.d Content Update, VCS push, Framework Deploy
PDF response RC, CDN* RC {config}.{site_id}.{environment_id}.d Content Update, VCS push, Framework Deploy
JSON response - - - -
Original Image CDN RC {config}.{site_id}.{environment_id}.f Image revision update
Transformed Image RC, CDN RC {config}.{site_id}.{environment_id}.f Image revision update
Virtual File CDN RC {config}.{site_id}.{environment_id}.f Image revision update
Static File (VCS) CDN - {config}.{site_directory}.s VCS push

Cache Controls in the Templates

There several aspects of caching which are possible to control from the template code.

Cache Expiry

It is possible to explicitly set cache expiry time either from a date/time string with an optional string format or DateTime object:

{$_response->setCacheExpiryDateFromString('2022-12-31 23:59:59')}
{$_response->setCacheExpiryDateFromString('23h 15m 03s', 'H\h i\m s\s')}
{$_response->setCacheExpiryDate($date)}

Also, it is possible to set Cache Time to Live (TTL) value relative to the current time, in seconds:

{$_response->setCacheTTL(300)}

The instruction above will set response cache expiry time to 5 minutes from now.

Vary Parameters

Vary parameters are automatically set whenever $_request->getParameter() method is called:

{$_request->getParameter('foo')}
{$_request->getParameter('lang')}

It is also possible to explicitly specify the list of vary parameters using $_request->addCacheVaryParameter($paramName) or $_request->setCacheVaryParameters($params) which accepts an array of parameter names:

{$_response->setCacheVaryParameters(['foo','lang'])}

Caching Prevention

Caching of the current response can be prevented by calling:

{$_response->preventCaching()}