Developers · Best Practices
Dynamic Cache
Last updated 2 November 2026
Dynamic cache works similarly to static cache. You can use it to cache the whole page, but the difference is that it triggers authorization, which also works for logged-in users. The cache will be invalidated whenever you change something on the page and deploy it. In reality, it's rarely possible to cache the whole page or layout (this is why
A dynamic cache is used when a page is 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 vast amount of visitors flooding from a marketing campaign. Data cached on those pages usually do not need to be real-time because it is not critical. Regarding products on the homepage example: Last viewed products on the homepage, it is not vital for this list to be real-time; it can be cached for 60 seconds or even more to improve the site's performance.
Explanation
A dynamic cache is defined in page configuration.
---
dynamic_cache:
expire:
layout:
key:
---Details for each of the configuration options are displayed in the table below.
| Properties | Description | Default |
|---|---|---|
expire |
Number of seconds since cache creation, after which it will not be taken into consideration when requested again. If If If you update a page either by sync or deploy, it will invalidate the cache, no matter if the expiration time has passed or not. |
none |
layout |
Make the layout part of the cached page. |
false |
key |
Unique identifier for the page. If you cache a page for 10 seconds and the If the page content does not depend on arguments, it's best to restrict |
full page URL with query params. For example https://example.com?my_arg=1 |
Example 1
app/views/pages/dynamic-cache.liquid
---
dynamic_cache:
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. You might cache a page this way to refresh its content after you add new products to the store you manage.
app/views/pages/dynamic-records.liquid
---
dynamic_cache:
layout: true
key: >
{%- assign tables = 'modules/n_plus_one/programmer,modules/n_plus_one/company' | split: ',' -%}
{%- graphql result = 'records_updated_at', tables: tables -%}
{%- assign record = result.records.results | first -%}
{{ context.page.slug | append: record.updated_at }}
---
{% assign tables = 'modules/n_plus_one/programmer,modules/n_plus_one/company' | split: ',' %}
{% graphql result = 'get_records', tables: tables %}
{% assign records = result.records.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>
<ul>
{% for item in records %}
<li>[{{ item.updated_at }}] {{ item.table }} - {{ item.properties.email }}</li>
{% endfor %}
</ul>Both queries take the table names in the
app/graphql/get_records.graphql
query records($tables: [String!]) {
records(
per_page: 3
sort: { updated_at: { order: DESC } }
filter: { table: { value_in: $tables } }) {
results {
properties
updated_at
table
}
}
}app/graphql/records_updated_at.graphql
query records_updated_at($tables: [String!]) {
records(
per_page: 1
sort: { updated_at: { order: DESC } }
filter: { table: { value_in: $tables } }
) {
results {
updated_at
}
}
}