Adventures in Drupal 7 Caching

(This post will be updated as we get a clearer idea of what is going on and how all the pieces fit together)

We have made quite a few sites in Drupal 7, the largest being Drupal has evolved into a really powerful framework that can enable you to bring together all kinds of data in a variety of imaginative ways. However, you also need to know quite a bit about caching to get the site to load at speeds that people expect nowadays.

There are many different caching mechanisms that one can use with Drupal – this post aims to make clear how they can all fit together.

Out of the box caching mechanisms:

Page caching for anonymous users: This basically means that the entire page HTML is stored in the cache_page table in the database, and rendering the page requires just one trip rather than the multifarious queries normally required to build a page.

Block caching: If you enable this, then blocks will be cached for both anonymous and authenticated users. (Note that if you are not logged in and visit a page that has been cached for anonymous users, then the block content in that page will be cached no matter what – see this post). If you have a module that calls the hook_node_grants hook, then this is disabled to prevent people possibly seeing links in cached blocks to pages they shouldnt be seeing. However, this seems to be overriden by using the Drupal 7 block_cache_alter module (need to test this further). Note that block caches are flushed every time content is created or updated on the site – you can cache per page, role or user but there doesn’t seem to be much finesse in terms of minimum lifetimes etc.

Not out of the box

Views – Views can generate some pretty long queries, for example some of the queries mentioned above are querying 10 tables. So caching these are a must to have the site render quickly for authenticated users (as with block caching, the HTML output of these views are cached for anonymous users). For example, our feed displays have a caching lifetime of 1 hr, and many of our other content displays have a lifetime of 6 hours. Note that for block displays, Views offers options both for caching the view content and the surrounding block. We’re still evaluating in what cases this is useful and what other cases this could be counter productive (setting and flushing caches can be quite expensive processes)

Caching customised content – It is very easy to cache customised content using the cache_get and cache_set functions (for a very good guide, see here). You can set minimum cached lifetimes. As with views, we are still evaluating if it is a good idea to enable block caching for customised blocks whose content has already been cached in this manner.

Block cache alter – Right now, we are using it to cache the content of custom blocks. It seems to work straight out of the box in D7, even though we have modules with node access restrictions enabled (namely Domain Access). Right now we are mainly using it with user-created custom blocks (ie those using the block module).

Boost – This module creates static HTML pages and serves them instead of making Drupal/PHP/MySQL do the work. As of writing, the D7 version is workable and we are using it on several production sites. It seems to use some of Drupal’s native settings, so we’re still trying to see whats what there. It’s not yet as full featured as Drupal 6. I think the delay is bacause there is a push to try and integrate the settings into some kind of centralised caching API (see the pluggable caching section below) We have had issues with it on a few occasions, for example caching white screens (see this issue) In one instance on another site, I had to disable it because the cache wasnt being flushed effectively on node update. However, both those occasions we were using different hosting set ups to normal.

Pluggable caching

Drupal 7 has a pluggable caching backend. Basically what this means is that you can specify in your settings.php that instead of using Drupal’s database cache_* tables, the cache will instead be handled by another module. You can even configure different caching mechanisms to replace different cache tables.

Memcache/APC – Object based caching, which is faster then Database caching by many multiples. You can configure different modules to handle different caches – for example one recommended variant is to use APC to handle caches which do not change often like ‘cache’ and ‘cache_bootstrap’, Memcache to handle caches which can get large or change often like ‘cache_field’ and ‘cache_menu’ and leave Drupal’s database to handle ‘cache_filter’. These do require Mamcached/APC and their associated PHP PECL libraries to be installed on the server, but if you are on a managed VPS, your hosting people might do it for you.

Authcache – In its default state, this module will cache pages in the Drupal cache_page table for authenticated users just as the native caching does for anonymous users. However, this means pages will be served the same way for each role no matter what. Authcache offers a little bit of latitude to customise the user experience eg a special page variable to print the current user name. Right now we aren’t using it, as the D7 version hasnt yet developed a similar variable to print tabs.

You can use this module in combination with other cache backends eg memcache to speed up caching for authenticated users.




Comments are closed.