Tangling with the Template Cache

The ColdFusion template cache is an interesting beast; one which taught me a great deal about caching. I’ll be discussing the design of the template cache in this post, along with the rationale behind the approach that was taken, and some explanation of interesting behaviours that the template cache exhibits. Before we venture further, please do read An Introduction to Caching - you’ll need that information to understand the rest of this post.

What is the template cache?

For those who don’t know, the template cache is where ColdFusion stores compiled CFM and CFC templates in memory. When a template is executed for the first time, it is compiled to Java bytecode, and then stored in the template cache. Subsequent requests for the template use the compiled form of the template stored in the template cache, saving the overhead of having to read a file from disk, or even having to recompile a template. Templates are typically recompiled only when the CFM or CFC is modified, though if you’ve configured CF to not store compiled templates to disk, they will be recompiled any time they’re not found in the template cache.

Template cache configuration is managed from the ColdFusion Administrator under Server Settings > Caching. You can manage cache size and a couple of other settings, which I’ll get to later, on this page.

Requirements

The template cache has very specific requirements that call for an interesting combination of caching strategies:

  • It should maintain as many templates as possible in memory, so that templates can be retrieved rapidly, and so executed efficiently.
  • In case increased traffic to a site causes a spurt in demand for templates across the site, it needs to be able to grow itself beyond its configured size. If it were not to grow itself, then it could end up thrashing as it rapidly moves templates in and out of the cache, to deal with high volumes of requests for different templates, degrading server performance, and possibly even causing a server crash.
  • It must not grow itself so much that it causes memory consumption issues for the server as a whole.
  • It must shrink in size when demand for templates across ths site reduces.
  • It must not shrink below a specified size. If we were to allow the cache to shrink down to zero, even recently used templates would be dropped off. Leaving issues of memory aside, we want to keep at least some minimum number of recently used templates always available so that the server stays responsive to demand.

Sounds confusing? I’ll come back to these requirements as we go along, and then, hopefully, you’ll understand why we need things to be the way they are.

Caching Strategies

To fulfill the requirements I’ve outlined above, the template cache adopts a combination of caching strategies - in a nutshell, it uses a soft cache stacked on top of a LRU cache.

Why this approach? The LRU cache ensures that recently used templates are always maintained in memory for fast access. The soft cache stacked on top of it provides a means for the template cache to grow when it needs to, but ensures that it will never grow out of bounds, allowing the Java garbage collector to keep its size under control.

Contrary to what you might think, the template cache size that is configured via the CF Administrator does not specify the maximum number of templates that the cache may hold. It actually configures the maximum size of the LRU portion of the cache; there will always be at least this many templates available in the cache. As must be obvious by now, the template cache as a whole can grow beyond this configured size in times of high demand, provided memory is available. As demand drops, the template cache size will drop back to the size of the LRU cache.

Tuning the Template Cache

By default, the template cache is configured to hold 1024 templates at a minimum. This by no means indicates that it will always store 1024 templates - if your site has fewer than this number, that’s how many the cache will store. For most, there will never be any reason to change this setting. For those who do play with the cache size, here are some guidelines:

  • If you turn it up too high (and you have an equivalent number of templates on your site), you run the risk of causing memory consumption problems in the JVM, since the LRU portion of the template cache will attempt to hold at least as many templates as you specify in memory, with no regard to overall memory consumption.
  • If you turn it down too low, there is a possibility that your site could become less responsive as demand peaks, since it will have to load and/or compile templates to get them into the cache.

There are a couple of other settings apart from the LRU cache size you can use to control behaviour of the template cache, both of which will affect overall performance of your server:

  • Trusted Cache: Turning this on saves the overhead of having to check whether templates have been modified. As the documentation suggests, this is ideal for production sites which don’t expect to see changes to templates.
  • Save class files: Saves compiled template class files to disk. Turning this on saves the overhead of having to recompile templates which have been compiled once already, but dropped out of the cache.

That’s it! Go ahead and play with your template cache; see if you can’t get that server running that little bit smoother…