Home / Comment permalink

When and how caching can save your site. Part 2: authenticated users

On my last blog post we looked to what Drupal achieves out of the box regarding Drupal caching. We understood how Drupal can cache pages for anonymous users and found solutions to avoid to bootstrap Drupal to serve a cached page (using a reverse proxy like Varnish or redirecting requests using Boost). We also saw that even if any of these tools is used, Drupal is also able to save cached versions of pages in the database. However, Drupal allows to plug transparently other caching backends that are faster:

  • Memcache is the most popular option to be used as Drupal caching backend. It is well supported by contributed modules and it is available to be used on Acquia Cloud. Memcache can be easily scaled to several boxes and memcache module allows assigning each Drupal cache type to a different cache bin. This allow to deploy the different bins in the different servers for instance without troubles. Memcached should however always live as close as possible to the web server, ideally even in the same box. Memcache is highly recommended for environments where partial caching is needed for authenticated users for instance.
  • APC is another option to store cached keys. APC is a popular opcode cache extension for PHP that can easily improve the performance of any website by caching in memory php scripts and avoid to read them from the disk. In a framework like Drupal that load many php files in each request, having APC installed is almost a must. Moreover, APC provides a keystore caching feature that can be used as a Drupal caching backend. Even if using APC might be fast then using memcache, the fact that it can not scale across several servers and in some configurations the memory allocated by a php process can not be shared with other processes, presents a significant disavantage when compared with memcached.
  • Other options include Redis , Filecache or MongoDB . All of them have modules available for Drupal in different stages of maturity, available for different versions in D6 and D7, providing different levels of support for Drupal caching.

A new caching backend for Drupal can help on speeding render of partial parts of Drupal pages, like blocks, views and nodes.
Replacing the default Drupal backend engine is most of the times a straightforward process of configuring settings.php to support a different caching backend and the settings needed by that backend. For memcache for instance you would use:

$conf['cache_backends'][] = 'sites/all/modules/memcache/memcache.inc';
$conf['cache_default_class'] = 'MemCacheDrupal';

Partial caching

Apart from providing high level page caching, Drupal can also cache different parts used in page generation. Those parts can be cached and reused the next times they are needed. Drupal core and popular modules are able of caching their results, both for anonymous and authenticated users, for instance:

  • Content caching: Node generation can be cached assuming that fields look similar to different users.
  • Block caching: Blocks can be deployed in several parts of pages and their results can be cached globally, or cached per page, roles or users.
  • Menus and menu links: Instead of gathering information about menus and menu links on all requests, their serialized version can be cached and reused.
  • Views: Views are usually used to grab results from the database and show them in different contexts of Drupal pages. Views module is able of caching rendered results or intermediate results that were grabbed from the database and still need to be rendered. Views caching API is smart enough to understand the context the view was generated: exposed filters and arguments can influence the view end result. Therefore when caching is active, filters and arguments are used as part of the caching key to guarantee that caching results are not saved wrongly.

Page caching for authenticated users

There is another solution to provide caching for authenticated users for Drupal 6. One of the factors that influence what users see in different pages are their permissions. Permissions in Drupal are controlled by roles and roles are assigned to users. In theory this allow site builders to define groups of users that would see different things in different pages, and therefore could always receive the same version of the page.
Let’s look to Drupal.org homepage for instance: only specifics tabs would be different from user to user and they probably could be customized using values that browser can customize using javascript. So there is not many reasons to not serve this page directly from cache and save processing time when serving the same page over and over again to authenticated users.
This is the reasoning behind authcache module. The module registers an extra cookie when the user logins with the user roles hashed in a key. Therefore without going to the database in each request the module can identify which roles do users have. The module allows configuring cached pages to be saved and served to different roles (from anonymous users, authenticated users and any other Drupal role). The module allows also configuring which paths should be cached or excluded from general caching strategy.
When a request is made the module would identify if the page could be cached for that path and that specific role. If that is valid that the page could have been cached, then Drupal accesses caches to analyze if a valid cached version is available. If the cached version is available, it is served directly to the users, if not it is normally rendered and it is saved to be served in the next request.
Authcache also saves extra cookies with values for user name and user email that can be used to be printed in the page template.
Authcache works as a wrapper caching backend that integrates well with other caching backends (Memcached and Cacherouter). Its installation is straight forward as you would be expecting, settings about the used caching backend will be automatically recognized:

$conf['cache_inc'] = './sites/all/modules/authcache/authcache.inc';

Authcache will automatically try to include the Cache Router or Memcache file include. If you are using a different cache module, you can define its path by setting:
['cache_inc_via_authcache'] = './sites/path/to/module/cacheinclude.inc';

The module configuration page located in the administrative performance settings page allows to configure all settings related with paths, roles and cache options. A debug mode is available to show to specific roles debug information that can help on understanding if caching is being set correctly. Authcache is currently stable for Drupal 6 and in active development for Drupal 7.

Avoiding the bootstrap

Normally when partial caching is used, Drupal needs to bootstrap to load the different cached elements which can still cost cpu time. Nevertheless, this can be avoided using Edge Side Includes and Varnish for instance: specific elements or blocks can be loaded each time a page loaded trough an internal call to the backend server. This can in help in situations where all the page need to be cached but a specific element need to have different caching settings or be totally customized according to the context. There are modules that can provide ESI integration with Drupal and can render several types of elements in paths that can be included in Edge Side Include calls. In a near future in Drupal 8 it is expected that render several elements via ESI calls gets much easier. That is one the main goals of the WSCCI initiative that you can follow in http://groups.drupal.org/wscci.

In this eBook, we show you how to optimize performance of your Drupal site without any knowledge of coding, server configuration, or the command line.


Posted on by Anonymous (not verified).

If your site makes extensive use of Panels and you have authenticated users, Panels-Hash-Cache is a great choice: http://drupal.org/p roject/panels_hash_cache

Posted on by Hernani Borges ....

Great tip when using panels to deploy landing pages, usually they are the ones that get more traffic.

Posted on by charlie (not verified).

Do not forget to set cache_form "back" to database cache!

Posted on by Ognyan Kulev (not verified).

...or use filecache for cache_form and other cache bins that usually have large entries. Disk space is usually much more than RAM, and filesystems are more suited for BLOBs, and files has their own caching layer in system buffers.

Posted on by Jakub Suchy.

The issue with filesystem caches is that in the new paradigm of scaling in the cloud (multiple webservers, load balancing layers), filesystem becomes your more expensive asset because scaling filesystems across multiple webservers is more difficult than adding a bit of memory to your memcache.

Posted on by Ullrich (not verified).

Does authcache module take care of node_access?

Posted on by Hernani Borges ....

Authcache will cache the entire page for specific roles. Therefore it will only make sense to use if you are controlling access to your nodes by different roles. If there are more variables that define access to your nodes and are not dependent on roles, then using authcache is a bad idea.

Posted on by valderama (not verified).

you mentioned content caching in your post. do you refer to the entity cache module (http://drupal.org/project /entitycache) or are there other solutions to cache content?

Posted on by Hernani Borges ....

Entity cache is a good module that allows to extend caching to entities likes users,comments, terms apart from nodes. Node caching is supported in drupal core. If you are using a database as a caching backend engine you will find several entries for cached nodes in table cache_content.

Posted on by Damien McKenna.

IMHO the best solution for authenticated caching is CacheTags (http://drupal.org/project/c achetags), especially Dick Olsen's fork (http://drupal.org/sandb ox/dixon/1341260) that will hopefully be merged into the main module. The key change with it is that objects are cached indefinitely until they're invalidated by the object being changed, e.g. a node's teaser in a view will be cached until the node is changed.

Posted on by lavoiesl (not verified).

If you are yo use partial page caching with Cookies or others cache-blocking headers, I suggest you take a look at this: http ://blog.lavoie.sl/2013/08/varnish-esi-and-cookies.html

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Filtered HTML

  • Use [acphone_sales], [acphone_sales_text], [acphone_support], [acphone_international], [acphone_devcloud], [acphone_extra1] and [acphone_extra2] as placeholders for Acquia phone numbers. Add class "acquia-phones-link" to wrapper element to make number a link.
  • To post pieces of code, surround them with <code>...</code> tags. For PHP code, you can use <?php ... ?>, which will also colour it based on syntax.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <h4> <h5> <h2> <img>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.