4.6.x bootstrap.inc cache_set($cid, $data, $expire = CACHE_PERMANENT, $headers = NULL)
4.7.x bootstrap.inc cache_set($cid, $data, $expire = CACHE_PERMANENT, $headers = NULL)
5.x cache.inc cache_set($cid, $table = 'cache', $data, $expire = CACHE_PERMANENT, $headers = NULL)
6.x cache.inc cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL)
6.x cache-install.inc cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL)
7.x cache.inc cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT)

Stores data in the persistent cache.

The persistent cache is split up into several cache bins. In the default cache implementation, each cache bin corresponds to a database table by the same name. Other implementations might want to store several bins in data structures that get flushed together. While it is not a problem for most cache bins if the entries in them are flushed before their expire time, some might break functionality or are extremely expensive to recalculate. The other bins are expired automatically by core. Contributed modules can add additional bins and get them expired automatically by implementing hook_flush_caches().

The reasons for having several bins are as follows:

  • Smaller bins mean smaller database tables and allow for faster selects and inserts.
  • We try to put fast changing cache items and rather static ones into different bins. The effect is that only the fast changing bins will need a lot of writes to disk. The more static bins will also be better cacheable with MySQL's query cache.


$cid: The cache ID of the data to store.

$data: The data to store in the cache. Complex data types will be automatically serialized before insertion. Strings will be stored as plain text and are not serialized. Some storage engines only allow objects up to a maximum of 1MB in size to be stored by default. When caching large arrays or similar, take care to ensure $data does not exceed this size.

$bin: (optional) The cache bin to store the data in. Valid core values are:

  • cache: (default) Generic cache storage bin (used for theme registry, locale date, list of simpletest tests, etc.).
  • cache_block: Stores the content of various blocks.
  • cache_bootstrap: Stores the class registry, the system list of modules, the list of which modules implement which hooks, and the Drupal variable list.
  • cache_field: Stores the field data belonging to a given object.
  • cache_filter: Stores filtered pieces of content.
  • cache_form: Stores multistep forms. Flushing this bin means that some forms displayed to users lose their state and the data already submitted to them. This bin should not be flushed before its expired time.
  • cache_menu: Stores the structure of visible navigation menus per page.
  • cache_page: Stores generated pages for anonymous users. It is flushed very often, whenever a page changes, at least for every node and comment submission. This is the only bin affected by the page cache setting on the administrator panel.
  • cache_path: Stores the system paths that have an alias.

$expire: (optional) Controls the maximum lifetime of this cache entry. Note that caches might be subject to clearing at any time, so this setting does not guarantee a minimum lifetime. With this in mind, the cache should not be used for data that must be kept during a cache clear, like sessions.

Use one of the following values:

  • CACHE_PERMANENT: Indicates that the item should never be removed unless explicitly told to using cache_clear_all() with a cache ID.
  • CACHE_TEMPORARY: Indicates that the item should be removed at the next general cache wipe.
  • A Unix timestamp: Indicates that the item should be kept at least until the given time, after which it behaves like CACHE_TEMPORARY.

See also



34 calls to cache_set()
archiver_get_info in includes/common.inc
Retrieves a list of all available archivers.
book_menu_subtree_data in modules/book/book.module
Gets the data representing a subtree of the book hierarchy.
CacheClearCase::testClearArray in modules/simpletest/tests/cache.test
Test clearing using an array.
CacheClearCase::testClearCid in modules/simpletest/tests/cache.test
Test clearing using a cid.
CacheClearCase::testClearWildcard in modules/simpletest/tests/cache.test
Test clearing using wildcard.

... See full list


includes/cache.inc, line 141
Functions and interfaces for cache handling.


function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
  return _cache_get_object($bin)
    ->set($cid, $data, $expire);


alanom’s picture

...pass $cid and $bin to the misleadingly named cache_clear_all()

alandarev’s picture

Simple example of using cache in your functions

function steam_get_username2($steam64)  {
  if($cached = cache_get('steam'.$steam64, 'cache'))  {
    $username = $cached->data;
  if(empty($username)) {
    $username = 'blank'; // Expensive code here
  cache_set('steam'.$steam64, $username, 'cache', 60*60); //1 hour
  return $username;
chrisroane’s picture

Shouldn't the expire time be added to the current time?

Like this:

cache_set('steam'.$steam64, $username, 'cache', time() + 60*60);
RogerB’s picture

cache_set() is being called on every invokation. It should only be called when the data is rebuilt.

function steam_get_username2($steam64)  {
  if($cached = cache_get('steam'.$steam64, 'cache'))  {
    $username = $cached->data;
  if(empty($username)) {
    $username = 'blank'; // Expensive code here
    cache_set('steam'.$steam64, $username, 'cache', time() + 60*60); //1 hour
  return $username;
drewish’s picture

Use REQUEST_TIME rather than time().... but yeah you'd need to treat it as a timestamp so 360 would be some time in 1970.

Edit: this was supposed to be a reply to chrisroane's comment but I guess I clicked the wrong reply link.

chrisroane’s picture

Good catch!

chrisroane’s picture

The only way I could get the caching to work as expected in a custom function was to also use &drupal_static(__FUNCTION__) ....Below is a simplified version of what I got working:

function _tbf_cart_get() {
  // This makes sure we only do the heavy lifting from this module one time
  // per page load.
  $cart = &drupal_static(__FUNCTION__);
  if (!$cart) {
    $cache_id = 'tbf_cart:cart:' . $_SESSION['cart']['orderid'];
    // Grab the data from the cache.
    $cache = cache_get($cache_id, 'cache');
    if ($cache && !empty($cache->data)) {
      $cart = $cache->data;
      return $cart;
    // Add the data to $cart...
    // Add the data to the cache.
    cache_set($cache_id, $cart);
  return $cart;
technicalknockout’s picture

The $expire option CACHE_TEMPORARY says

Indicates that the item should be removed at the next general cache wipe.

How is the next general cache wipe triggered? Is it triggered by cron jobs? Is it triggered every hour or every day?

forestmars’s picture

@technicalknockout Yes, it happens on cron run by default, so how often depends on what you have cron set to.

xeeshangulzar’s picture

Is there any way that i can wipe cache after some minutes?

bfr’s picture

Try the Elysia cron module for more fine grained control of the cron service. If that is not enough, implement cache_clear_all() or take a look at the code of drupal_flush_all_caches() for more ideas.

Not 100% sure but i think Rules could also do this.

sebas5384’s picture

Example with strtotime(), maybe for a more clean and easy way for getting a cache to expire in 6 hours:

$cache_time = '+6 hour';
$expire = strtotime($cache_time, time());
cache_set('resource:' . $name, $result, 'cache_clients', $expire);

This way I can have a select form element with values like '+1 hour', '+6 hour', '+1 day', etc...


cbiggins’s picture

Very nice and clean example. Thanks.

rvelhote’s picture

This is very lame but the $expire parameter, when set in a form of a Unix timestamp, is ignored if the parameter cache_lifetime set in admin/config/development/performance is not set to X minutes.

This will cause cache_get to return expired entries!

Sadly, the description for the cache_lifetime parameter is incorrect because it mentions "cached pages" so one would assume that it's applicable to whole pages and not specific cache entries.

This is not documented and should not even happen otherwise it destroys the purpose of setting an expire parameter.

rcls’s picture

I can confirm there is an issue with the $expire parameter. I spent last night testing this issue out with a simple retrieval of data and storing it to the cache and setting the $expire to time() + 300 (5 minutes). I then printed out the time, the time the cache was set and expiration. The time the cache was set and expiration worked fine, but I noticed that even after 30 minutes this cache would still persist.

A simple way to go around this was to check if time() was bigger than the $cache->expire and then clearing out the cid with cache_clear_all(). An example code is below.

function cache_data($cid) {
    $data = &drupal_static(__FUNCTION__);

    $example_data = 'This is a string';

    if (!isset($data)) {
      $cache = cache_get($cid);

      if (!empty($cache->data)) {
          if(time() > $cache->expire) {
            cache_clear_all($cid, 'cache');
            cache_set($cid, $example_data, 'cache', time() + 300);
           else {
             $data = $cache->data;
      else {
         cache_set($cid, $example_data, 'cache', time() + 300);

    return $data;
rakesh.gectcr’s picture

if ($cached = cache_get('db_index', 'cache')) {
$tables = $cached->data;
else {
$tables = drupal_get_schema();
// Setting the data to drupal cache.
cache_set('db_index', $tables, 'cache', CACHE_TEMPORARY);

Anonymous’s picture

$data = cache_get('db_galaxy', 'cache');
if ($data && (time()-$expire < $data->expire)) {
$data = $data->data;
echo "cache RECOVERED";
else {
$data = time();
cache_set('db_galaxy', $data, 'cache', time()+$expire);
echo "cache RENEWED";