This project is not covered by Drupal’s security advisory policy.

The new 2.0-rc1 release is NOT backwards compatible with the previous version (not even with some 2.x-dev releases). If you're planning on using it, you should completely uninstall the previous version. Version 2.0 has gone through some serious refactoring and also comes with a MongoDB backend, which greatly improves performance on heavy-traffic sites.

Please note that the Drupal 6 version of this module is no longer supported. It is still available, but won't be developed any further.

Cache Control is a module for integrating your site with the Varnish HTTP accelarator (and other external HTTP-caches) in a fashion that not only allows for caching pageloads for anonymous users but also for authenticated users.

In order to make best use of this module, you need to write some custom code. In other words, this is a module for advanced use and cannot be considered a component that will make your site perform better just by being enabled.

Comparison to the ESI-module

The ESI module ( offers solutions to similar problems as the Cache Control module. Cache Control has a slightly different approach, with some of the main differences outlined below:

- A page with ESI blocks needs to be fully compiled before it can be shown to the user. If just one of the requests fetching user-specific content hangs, the whole page is waiting for that one block. With cache control, most of the page is available as soon as Varnish returns the anonymous version, and the user-specific content is added once it's ready.

- The ESI module currently supports block content only. Cache Control allows you to cache any content for registered users, although it does require that you write custom code in your own modules in order to do that.

- In case of pages that have a large number of user-specific blocks, ESI makes as many requests to Drupal (assuming none of the user-specific blocks are cached) as there are blocks. Cache Control makes one (or two, in case there is both user- and role-specific content). Even if the ESI-blocks are in Drupal's cache, bootstrapping Drupal is hard work for the server.

- The philosophy behind Cache Control tries to keep as much code as possible on the Drupal side. After all, there are a lot more people that can do Drupal than people that can do vcl. We try to keep the vcl configuration unchanging and as simple as possible. Any new things should require changes on the Drupal side only.

- Cache Control should be usable with any reverse proxy, not just Varnish. It hasn't been tested with anything else yet, but the architecture doesn't depend on anything Varnish-specific.

How does it work?

The basic idea of Cache Control is to check whether the current pageload can be cached by Varnish, and if that is the case, switch the execution context of the pageload to that of anonymous user's (in order to ensure cacheability). When a user requests a page that is found in the cache, it is served by Varnish and user-specific parts of it are dynamically added on it via AJAX, if the user has authenticated. For anonymous users, the content will be served as-is, with no Drupal involvement required.

Some details

When a pageload is made, the following checks are performed (cache_control_init()):

  • If it's a POST request, an access denied page or just a non-cacheable path, no-cache headers are sent.
  • If it's a cacheable path, the execution context for the whole pageload is switched to an anonymous user (in order to ensure the cached result doesn't contain any personalized data). The menu item access callback is re-executed for the anonymous user, and if it still passes, the pageload is actually cached (otherwise the execution context is switched back to the current user and pageload is done normally without caching). HTTP headers allowing caching are sent at this point.

If there are components on the page that may require personalized content, they notify cache_control by invoking hook_cache_control(). The implementation of this hook (cache_control_cache_control()) stores the function and arguments needed to generate the content and adds a caching id to the page Javascript. The invoking module must react to the return value of the implementation: if the pageload is being cached, the generated content is put into a hidden container (this content is used for anonymous users) and a placeholder (a throbber, a 'please wait' message or whatever) is made visible on the site.

The JS frontend (cache_control.js) checks if the user is anonymous (based on a cookie). If yes, the hidden containers created before are shown and no AJAX call is made. If the user is authenticated, an AJAX call with the caching id is made to _cache_control/get_components/%. The backend executes the functions needed to generate personalized content and returns the resulting HTML. The JS frontend replaces all placeholders with the generated content (based on the HTML ids) .

Not all details were described here, but this should give a good idea about how the module works together with Varnish.

Cache purging: a separate module, Cache Control Purge, implements some purging functionalities. Basically it sends HTTP PURGE requests to the varnish servers (and allows also manual purging). It has some default purge conditions (such as when a node is updated, its path is purged) and also offers a hook_cache_control_purge() which other modules can implement if they need to react to content being updated or deleted.

Is it secure?

It may feel discomforting to have Varnish cache pages requested by authenticated users. Doesn't it imply that users' private data may be cached by Varnish and served to the entire world. Fortunately, no: When executing a page load that will end up in the cache, it will always be executed as an anonymous user, even if the request was made by an authenticated user.

Does it work with my favorite contrib module?

Cache Control plays fairly nice with others. However, we've had to write some code for specific modules in order to keep things from breaking apart. Some examples:

  • CAPTCHA: Forms with CAPTCHA challenges get a special treatment.
  • WYSIWYG: You may need to manually initialize your WYSIWYG profiles

Let us know if a module you're using doesn't get along with Cache Control.

Automated block support (D7 only)

There is an experimental feature that allows you to enable cache control for any Drupal block, no custom code required. Cache Control adds an "Enable Cache Control for this block." checkbox on the administration of each block. This feature hasn't been tested extensively on live sites and may still have some glitches.

How are we planning to develop this module further?

We have drafted a roadmap for this module and are planning to follow it in a rapid fashion. At least the following development needs have been identified (in order of priority):

  1. Admin interface rewrite (both cache_control and cache_control_purge). The current admin interface is a bit unintuitive and hasn't been built according to all best Drupal practices.
  2. Explore the possibility to replace parts of cache_control_purge by utilizing either Varnish HTTP Accelerator Integration or Purge module.
  3. More granular control over pages that can/cannot be cached
  4. More granular (e.g. role-based) control over what needs to be built per user after a pageload. This is expected to further improve the performance of this module.
  5. Make sure the module plays nice out-of-the-box with as many contrib modules as possible.
  6. Tools/practices to help developers to automate the use of this module as much as possible; the target is to minimize the amount of custom code needed.

We welcome any additional proposals for further development.

Who is maintaining this module?

Cache Control is maintained by Exove Ltd. We have also received contributions from A-lehdet.

Who is using this module?

Cache Control is currently being used in, a community-driven blogging site implemented by A-lehdet and Exove.

Please, let us know if your site uses Cache Control.

Project information