Managing MODX Revolution Resource Caching for Faster Page Loads
Learn how MODX caches parsed resources, when to mark them uncacheable, and how to verify cache hits to improve performance without serving stale content.
20 Aug 2026, 12:48 UTC

Problem: Slow page loads despite simple templates
You have a MODX Revolution site with a handful of templates and a few snippets, yet page load times feel sluggish during peak traffic. Each request appears to re‑parse the same resource markup, wasting CPU cycles.
Thesis
By understanding how MODX stores parsed output in the modx_site_content cache table, you can enable caching for static resources, fine‑grain snippet execution, and verify cache hits to achieve measurable speed‑ups while avoiding stale data.
How MODX Resource Caching Works
When a resource is published and marked Cacheable, MODX runs the parser once, saves the fully rendered HTML in the content field of the modx_site_content row, and serves that string directly on subsequent requests. If the resource is uncacheable, MODX re‑executes the parser and any uncached snippets on every hit.
System settings control the behavior globally:
cache_expires– seconds after which a cached entry is considered stale (default 0 = never expires unless manually cleared).use_udperms– when enabled, MODX checks user permissions before serving a cached copy, preventing permission leaks.cache_disabled– set toYesto bypass all resource caching (useful for development).
Configuring Cacheability per Resource and Snippet
Resource level
- Open the resource in the MODX Manager.
- In the Settings tab, toggle the Cacheable checkbox.
- Save. The change takes effect immediately; the next front‑end request will either write or read from the cache table.
Snippet level
Snippets can be cached individually using the cached modifier:
[[!MySnippet]]
[[MySnippet]]
If a snippet depends on the current user, session, or request‑specific data, leave it uncached; otherwise, caching reduces redundant PHP execution.
Worked Example: Turning a Blog Post Cacheable and Verifying the Hit
Scenario: A blog post resource (ID 42) contains static markup and a snippet that displays the post title only.
- Ensure the resource is marked Cacheable.
- Make sure the snippet call uses the cached form:
[[$BlogTitle]](assuming the snippet is namedBlogTitle). - Clear the cache to start clean:
$modx->cacheManager->clearCache();(run this in a console script or via Site → Clear Cache in the Manager). - Request the page in a browser:
https://example.com/blog/post-42. - Open Chrome DevTools → Network, reload, and check the response headers. You should see
X-ModX-Debug: HITif you added&debug=1to the URL. - Alternatively, tail the MODX log (
core/cache/logs/error.log) withshow_logenabled; you will see a line like[2026-10-13 08:30:00] (INFO @ /index.php) Cache hit for resource 42.
After the first request, subsequent reloads should show a markedly lower Time in the Network tab because PHP parsing is skipped.
Trade‑offs and Limitations
- Stale data: If a resource relies on external data (e.g., a weather API) and remains cacheable, visitors see outdated content until the cache expires or is manually cleared. Mitigate by marking such resources uncacheable or by using a short
cache_expiresvalue. - Permission‑aware caching: With
use_udpermsenabled, MODX will not serve a cached copy to a user lacking the required policy, but the first request for each permission level still populates the cache. This can cause multiple cache entries for the same resource. - Development noise: Aggressive caching can hide syntax errors. During active development, set
cache_disabledtoYesor add theuncacheableflag to resources you are editing.
Practical Way to Check Your Configuration
Run the following SQL query (requires database read access) to inspect the raw cached content for a resource:
SELECT id, pagetitle, content FROM modx_site_content WHERE id = 42;
If the content column contains fully rendered HTML (including snippet output), the resource is being served from cache. If it contains only placeholder tags (e.g., [[$BlogTitle]]), the resource is either uncacheable or the cache has been cleared.
Actionable Closing
Start by auditing a few high‑traffic resources: toggle the Cacheable flag, verify cache hits with &debug=1 or the MODX log, and measure the impact in Chrome DevTools. Reserve uncaching for resources that truly need dynamic data, and keep an eye on the cache_expires setting to balance performance with freshness. This approach gives you repeatable, measurable speed improvements without sacrificing content accuracy.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.