Disabling the cache for reals

Submitted by Larry on 11 January 2009 - 7:21pm

Drupal has a very aggressive caching system. While site admins can disable the page cache or CSS compressor very easily, many other caches are not so easy to disable. Think of the menu system, or the theme system, or filter content, or any number of other things that get cached.

In a production site, that's exactly what you want. No Drupal site would be able to handle even moderate traffic if every single registry cache had to be rebuild on every page load. For development, however, it can frequently be a huge pain to have to clear the cache every time you're trying to track down a bug in a menu definition or a CCK field definition.

There's an admin button to clear the cache on the Performance page, but it's not all that useful for intensive debugging. The Devel module (which you are using, right?) offers a handy "clear cache" button, but that doesn't always work if you're, say, debugging a form submission. Fortunately, Drupal makes it easy for us to disable those caches, too, although not through the admin.

The cache system is one of many systems in Drupal that supports swappable include files as a way to offer alternate implementations. As of Drupal 6, Drupal even ships with a cache-install.inc file. As the name suggests, it's intended for use in the installer where you want to totally skip all caching, since there's no database to cache to yet. The code in the file is dead-simple. It's just empty implementations of the standard cache functions, with the net result that nothing ever gets saved to the cache and all cache lookups behave as if nothing is cached. Nice and easy.

Who says the installer gets to have all the fun, though? You can switch your development site to use the installer cache quite easily, thereby bypassing nearly all Drupal caching. To do so, simply uncomment the $conf array defined in settings.php and add the following line:

<?php
$conf = array(
  // ...
  'cache_inc' => 'includes/cache-install.inc',
  // ...
}
?>

That tells Drupal to use the cache-install.inc file instead of cache.inc, thereby disabling the cache entirely across the entire site. (Some systems get build up elsewhere than in the cache tables, like the menu system, so it won't take care of everything, but it does cover a great deal.)

There is, of course, a huge performance hit for doing that. The menu and theme systems must be rescanned on every page load, Views and CCK's registry hooks will get rescanned, all filtered content will have to be refiltered on every page load, etc. You probably don't want to leave it on for all of your dev work, and you absolutely want to remove that line before a site goes live. For debugging certain systems, however, don't forget that Drupal doesn't have to be quite so aggressive.

tstoeckler (not verified)

12 January 2009 - 4:08am

Is there anything that goes against making this an option in Drupal 7?
Right where you choose your caching level could be an option:
"Disable Menu and Theme registry caching (Only for Development sites; strong perfomance impacts)"
I think this would be scaring users who don't know what it is off (which is good in that case), but it would improve the site development process (for developers) IMO.

I'm not too keen on having UI for this in core. There needs to be a bit of a barrier for these more advanced things. There is no need to clutter the admin UI with a switch for absolutely everything. Usability has to be at the forefront to every sort of addition like that. It's important to keep the UI non-scary so as to keep the adoption rate high. New blood is key to winning the CMS race.

While I *totally* agree with the spirit of this comment, the implications of this kind of approach to user interface strike me as really troubling. As it leads to things like the pidgin-message-entry-box and the new-and-improved-but-less-configurable-GNOME, where developers thought they knew what their users wanted to do, than their users knew about themselves. Eh.

Could something like a "sudo" button/admin area be deployed to give an interface for features like this? Beyond just putting more admin/UIs behind more constrained access controls, it doesn't seem like it would be a bad thing to have a special section for "things that will probably break your site, but might be useful to your developer, don't try this at home"?

The alternative is, at least in a project like drupal, is that people go mucking around in code. Which isn't bad, really, but it's certainly a lot less user-friendly...

that sort of functionality can be easily added by modules like cache_disable, which developers can then add on demand

adding the functionality to core reduces performance for ALL drupal sites, which is kinda the opposite of the point of having caching ;)

you wouldn't want your auto manufacturer bolting on every cup holder and bling item that any consumer might conceivably need "just in case it helps", right?

developers are quite capable of finding modules like devel and installing them ...

hell, they even get paid to do it!

My solution is less elegant, but very useful during development. I believe it covers all caches in the system.
I have a shell script I named 'drupal_clear_cache', with the following content:

#!/bin/bash
MYSQL="/usr/bin/mysql"

cache_tables=`$MYSQL $1 -e "show tables like 'cache%'"|grep ^cache|xargs`
for table in $cache_tables; do
  $MYSQL $1 -e "truncate $table"
done

It accepts a single parameter - the database name. If you need a username password, add it in $HOME/.my.cnf (otherwise it's quite annoying).

[This was written for Linux, but I am sure Mac owners can use this too]