Make a clean sweep of commons Magento cache_lifetime workarounds usage

As I mentioned before, Magento cache policy API is based upon the Zend Framework Zend_Cache component. In this cache policy, there are three elements :

  • Cache key that defines the unity of the data we want to cache
  • Cache tags that allow to cluster our cache data
  • Cache lifetime that defines the duration within we consider that our stored data are valid and do not need to be rebuilt

My current topic will be about this latest point: cache lifetime. Its usage is quite simple: we define a duration while data will be stored in cache; during this period, data is always considered as valid, and so, not rebuilt. After that, even if data exists in cache, it will be rebuilt because considered as expired. Simple, no?

But we can hear so many things about cache lifetime usage that it seems interesting to evoke some specific points about its usage in Magento

What happens when Magento cache lifetime is specified as null?

When Magento cache lifetime is considered as null?

Excluding case you have defined a getCacheLifetime method which returns null value, this case occurs when you do not define the cache lifetime on one object which extends Varien_Object:

  • When rendering block content, Magento will call the getCachelifetime block method
  • If you have not defined a getCacheLifetime method, Magento will use Varien_Object __call method to retrieve cache_lifetime from attribute _data
  • If this index does not exists in _data, __call will return null

How is managed cache lifetime null value by Magento for block data?

All blocks extends Mage_Core_Block_Abstract. This class provides the following cache management:

As you can see, if lifetime is null the Magento Cache API will never fetch something from cache, so rebuild each time the block content. But also nothing will be stored in the cache(_saveCache method check if also there is a non null lifetime before save)

If you do not set up a cache lifetime for a block content, it will never be cached

How is managed cache lifetime null value by Magento blocks for non block data?

The cache API can also be used for other things than block output. This is the case for configuration cache. In this case, the control made by Mage_Core_Block_Abstract does not exist, and data will be cached: we’ll see that if cachelifetime duration is null for something else than block, it will use the default lifetime value like id you set up false as a cache lifetime value: 7200sec (2 hours)

What happens when cache lifetime is set up to 0 ?

Sometimes, we can hear that setting 0 as cache_lifetime duration disable cache. No, and this is for the following reason: 0 is a valid cache_lifetime duration.

Magento will define the timestamp until you consider your block content as valid with the following rule: current timestamp of data generation + cache_lifetime; so calculated expiration time will be the generation time. For sure, next time you’ll check if data is in cache and valid, you’ll compare new timestamp with expired timestamp, and there is a great probability that your current timestamp will be later.

Setting 0 as cache lifetime duration render your cached block content always expired

This is one of the worst case, because, each time you build content, you save it in cache, and invalidate it next time you’ll check it

What happens when cache lifetime is set up to false ?

The Zend Framework lifetime management for false values

Every cached backend used in Magento inherits from the Zend_Cache_Backend class

When saving content, Zend_Cache_Backend class will calculate the expiration timestamp trough the Zend_Cache_Backend::getLifetime method. If specified lifetime === false, backend use a default duration stored in its attributes

If you check Zend_Cache_Backend class, you’ll check that this value is hard_coded as 3600 sec (one hour)

But our content is stored longer, why?

Magento forces a default lifetime in its frontend

When the Magento cache API initializes the cache frontend object in the Varien_Cache_Core model, it merges cache options with directives options

This is the case for the cache_lifetime duration: default cache lifetime duration specified on Varien_Cache_Core is merged with directive options

But Varien_Cache_Core class extends Zend_Cache_Core. So when backend will be set up to frontend, we’ll use the native Zend Framework behaviour and so, merge frontend options as a backend directives.

So for all of our backend usage, because Magento forces usage of a Varien_Cache_Core frontend, default lifetime will be set up as 7200s

If your lifetime is set up to false, by default your block will be considered as valid during 7200s