- /
- /
Custom Module Caching in Drupal
Drupal has a great built-in caching mechanism that can significantly improve your site's performance, particularly for anonymous users. Once enabled, Drupal will automatically cache entire page views, on top of the automatic caching it does for menus, site variables, and content that has been filtered. Like most other aspects of Drupal, the caching system is extensible and is fully available to your custom module. There are two key aspects to learn for this technique: the Cache schema and the Cache API.
Drupal Cache Schema
In order to use the cache, you should understand the table structure. Your module has a choice of using the existing cache table, or creating one during install. Since your custom cache table must have the exact same schema as the built-in table, it is worth learning the structure.
Every cache table must contain the following six columns:
| Field | Type | Null |
|---|---|---|
| cid | varchar(255) | no |
| data | longblob | yes |
| expire | int | no |
| created | int | no |
| headers | text | yes |
| serialized | smallint | no |
cid
This is the primary key, and therefore the value for each row must be unique within the table. Unlike almost every other primary key (id) column in Drupal, this is not an integer, but rather a 255-character string. For example, you could use "events_summary" as a value for this column.
Note that, if you are using the built-in cache table, you may want to prepend your key's value with your module's name, to avoid namespace collisions. However, if your module has its own instance of a cache table, you may use whatever naming convention you prefer.
data
This column stores the actual data that you wish to cache. Notice that the type is "longblob" - this is generally the largest data store available. Also, as a "blob" type this column can store binary data, such as images and media content.
expire
This column determines the lifespan of the cached data, and can use either of two built-in Drupal constants. CACHE_PERMANENT will keep the item until explicitly removed, while CACHE_TEMPORARY will cause data to be removed at the next call to cache_clear_all(). A third option is to supply a Unix timestamp value, which acts just like CACHE_TEMPORARY but it will be removed only after the data specified.
created
This is a simple timestamp of when the row was entered into the table.
headers
This is used to store any HTTP headers that are part of an entire page cache, so it is used by core but not as often by custom modules.
serialized
Any PHP object or array must be serialized before it can be stored in the database. When adding a cache entry, Drupal will automatically do this conversion for you. However, the system must know whether the data had been serialized, so that it can properly be unserialized at retrieval. This column stores a simple binary 0 or 1 to indicate if this occurred.
Creating a Custom Cache Table
Since your custom cache table must have the exact schema as the Drupal's standard cache table, you can add this code to your module's install hook_schema by a simple copy-and-paste from the includes/system.install file. Just be sure to change the key to "cache_
Drupal Cache API
The Cache API has only a few functions that you need to learn in order to use it.
cache_set() This function accepts the cid, data, table name, expire and headers values for the data you wish to cache. Notice that "serialized" is not provided as a parameter - because Drupal takes care of this for you, there is no need to set the value manually. Similarly, the "created" value is applied automatically.
cache_get() This function is used to retrieve data from the cache and requires only the cid and table name. This function returns a basic object from which you can access table properties, for example $cached->data.
cache_clear_all() Use this function to clear either individual cache items up to an entire table. A great feature here is the first parameter for the "cid" accepts wildcard entries (as long as the third parameter is set to TRUE). So, you can use an asterisk "*" to tell Drupal to clear all of the entries for a table. Or, if you enter any text such as "modulename" then any cid's that start with "modulename" will be removed.
Note that this function observes the "expire" value set when creating a cached entry. If you provide a specific cid, then even a CACHE_PERMANENT entry will be removed. Conversely, if you do a general clear then only CACHE_TEMPORARY or timestamped entries will be removed.
Example of Drupal Caching
Now that you understand how it works, let's see an example in action. Assuming that your module has created its own cache table named "cache_example", we'll see if there is already cached data for our "events", otherwise we'll add it to the cache.
if (!$events = cache_get('events', 'cache_example')) {
// No cache found, so retrieve the data
// then add to the cache with expiration after 2 days
$events = example_getevents(); // returns an array of event objects
cache_set('events', $events, 'cache_example', time() + (2 * 60 * 60 * 24));
}
return $events;
Caching is an easy way to add significant performance gains to your custom module!

Nice summary
Does this information hook into the Drupal documentation somewhere. I haven't found any such information on Drupal yet. Could you provide a link?
Should there be a mention of hook_flush_caches()?
http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...
Cheers,
Kevin
You are correct that the Documentation area of drupal.org doesn't have much detail on this topic, only in the API reference areas that I already link to. My article was based on information gleaned from several sources, including articles I found online and reference books, as well as a bit of personal experience using it.
That's a great point about using hook_flush_caches, thanks for pointing that out.