Dynamic Page Cache

Last edit: Oct 26, 2022

Dynamic cache works similarly to static cache, you can use it to cache the whole page, but the difference is that it triggers authorization, so it works for logged in users as well.

Whenever you change something on the page and deploy it, the cache will be invalidated.
In reality, it's rarely possible to cache the whole page or layout (this is why layout is false by default).

Dynamic cache is often used when a page is very often visited (for example, a homepage with products from the database, a landing page with recently registered users) and you want this page to be fast and protected against the huge amount of visitors flooding from a marketing campaign. Data cached on those pages usually does not need to be real time, because it is not critical. Following products on the homepage example: Last viewed products on the homepage - it is not critical for this list to be real time, it can be cached for 60 seconds or even more to improve the site's performance.


Dynamic cache is defined in page configuration.



Unique identifier for the page.

If you cache a page for 10 seconds, and the key is blank, cache will be generated for the whole URL.
If the user changes anything in the URL, the cache will not be taken into consideration.

If the page content does not depend on arguments, it's best to restrict key to page.slug (and/or context.params.slug2 etc.).

Default: full page URL with query params. For example https://example.com?my_arg=1.


Number of seconds since cache creation after which it will not be taked into consideration when requested again.

If it is set to 0 and key is set, the cache will never expire by itself (updating the file would invalidate the cache though).
If key is blank and expire is 0, the page won't be cached at all.

If you update a page either by sync or deploy, it will invalidate cache, no matter if the expiration time has passed or not.

Default: none


Makes layout part of the cached page.

Default: false

Example 1


  expire: 10
  layout: true
Session ID: {{ context.session.session_id }} <br>
Authenticity Token: {{ context.authenticity_token }} <br>
Random Seed: {{ 5 | random_string }}

Example 2

You can cache a page depending on the last update of multiple records to invalidate the cache only when needed. This might be used to refresh page content after new products have been added to the store you manage.


  layout: true
  key: >
    {%- graphql record = 'records_updated_at' | fetch: 'records' | fetch: 'results' | first -%}
    {{ context.page.slug | append: record.updated_at }}
{% graphql records = 'modules/caches/get_records' | fetch: 'records' | fetch: 'results' %}

This page cache will be invalidated when any of the `programmer` or `company` records changes or when this page is updated. Whichever comes first. <br>

Random string: {{ 18 | random_string }} <br>

  {% for item in records %}
    <li>[{{ item.updated_at }}] {{ item.table }} - {{ item.email }}</li>
  {% endfor %}

query records {
    per_page: 3
    sort: { updated_at: { order: DESC } }
    filter: { table: { value_in: ["modules/n_plus_one/programmer", "modules/n_plus_one/company"] } }) {
    results {
      email: property(name: "email")
query records_updated_at {
    per_page: 1
    sort: { updated_at: { order: DESC } }
    filter: { table: { value_in: ["modules/n_plus_one/programmer", "modules/n_plus_one/company"] } }
  ) {
    results {

Source code and demos

Authenticity token example:

Records example:


We are always happy to help with any questions you may have.

contact us