Stand With Ukraine. Stop Putin. Stop War.

This article has been translated to Russian as well. Know of any other translations? Let me know!

MODX has very granular caching possibilities. Where Evo limits caching to just snippets and has other limits in terms of embedding tags in tags, MODX Revolution does not have these limits.

In MODX Revolution you can cache / uncache any tag you may use. That includes snippets, but also setting tags, placeholders, chunks and even lexicon strings. This article will talk you through some reasons when to call what cached in MODX Revolution (but it will save you most of the inner workings).

It is important to realize that, unless you're doing real advanced stuff and have overriden the core caching, the cache will be cleared when you: save a resource, element and to some extent settings. So basically, whenever your content or structure is changed - your cache will be updated to reflect that.

How do I tell MODX to (not) cache a certain tag?

Simply add in the exclamation mark (!) in front of the token. The token is a dollar sign ($) for Chunks, a plus sign (+) for placeholders, a percentage sign (%) for lexicons and an asterix (*) for resource fields and template variables. Snippets do not have a token.

Examples cached:


Example uncached:


Four Guidelines for Caching Strategies

  1. Cache everything you can.
    In general you will want to cache as much as you can - why should MODX retrieve the content from the database on every request, when it hasn't changed? While this may seem logical (and there is rarely any question on wether to use resource fields cached or not), the same applies to other tags. If the output of a snippet doesn't change on every request - why should MODX parse the snippet on every request? It shouldn't.
  2. User-specific output needs to be uncached.
    Anything that outputs user specific information will need to be uncached. Simple - any request could be made by different users, so it wouldn't do any good to load user-specific information from cache. This applies to snippets that interact with the user system (the Login package, a Wishlist component but also Quip for commenting), but also the somewhat less known [[!]] placeholder.
  3. Content related to URL parameters or POST data needs be uncached.
    If you're using a form which displays information about what was posted, you don't want that to be fixed and cached. So call that uncached as well. If your output is different depending on (non-id/q) URL parameters (for example a search results page), you will want to make sure the related snippet is not cached.
  4. Use custom caching when needed.
    If data (in a snippet) changes before the cache has been cleared, for example if data is retrieved from an external XML source that changes independantly to your MODX Content, you will want to use a custom caching method such as the getCache snippet or write your own caching within the snippet code.


Of course there are exceptions...actually, I could only come up with one so far: (Updated October 26th, came up with another one!)

  • site_url, http_host and related system settings may be called uncached. If you have a certain setup in which one resource+template combination may server multiple urls, you will want to make sure the related system settings are called uncached. One common application for this is your <base href="[[!++site_url]]"> tag for friendly URLs: you will want to be sure your assets are served from the same domain as the user visited. Wether you should force www/no www through htaccess is a whole different discussion, but that is very much related to this and a common cause for issues.
  • Snippets that (may) redirect or forward elsewhere will usually need to be uncached as the result may be empty, but the processing of the snippet does the work to redirect the user.

Common Errors

  1. Calling the "if" snippet uncached, when the subject is a resource field. Most likely caused by the documentation having uncached examples, a lot of people mis-use the If snippet by not caching it when the subject is static for the cache lifetime.
  2. Calling the "Wayfinder" snippet uncached. Please don't! Wayfinder especially can take a good performance hit on your website with larger menus. The only valid reason I can come up with to call Wayfinder uncached is when the output is user specific (member-only area, for example).
  3. Uncaching placeholders in chunks that are used as templates in snippets. Uncached placeholders are processed at the last possible time, and calling them uncached in a template will leave them in tact and they wont get replaced by the snippet, but instead by the core parser long after the snippet is done. (This behavior has seen some changes/bugs in the 2.1.x releases, so it could be that this is different in the latest release - I haven't actually checked in much detail recently.)

What are the errors you have made that you spotted in the above lists? Or do you have other caching tactics or questions? Share below!

Based on a comment from Marc Hinse, a follow-up to this post has been written discussing how nested caching works in MODX Revolution.