I'm looking for a definitive answer here. When object caching is enabled, where do options and transients end up living?

By default, both are stored in the database. But I've heard some references that memcache will store them elsewhere and APC will do something else entirely. Where, exactly, will this data be persisted in both cases?

3 Answers
3

WordPress, by default, does a form of "Object Caching" but its lifetime is only a single page load.

Options are actually a really good example of this. Check out this answer for more info. The summary:

A page starts

All options are loaded with a simple SELECT option_name, option_value from $wpdb->options statement

Subsequent requests for those options (eg a call to get_option never hit the database because they are stored with the WP cache API.

Options always "live" in the database and are always persisted there -- that's their "canonical" source. That said, options are loaded into the object cache so when you request an option there's a 99% chance that request will never hit the database.

Transients are a bit different.

WordPress allows you to replace the cache api with a drop-in -- a file that gets placed directly in your wp-content folder. If you create your own cache drop in or use an existingplugin, you can make the object cache persist longer than a single page load. When you do that, transients, change a bit.

Let's take a look at the set_transient function in wp-includes/option.php.

Hmmm $_wp_using_ext_object_cache? If it's true, WordPress uses the object cache instead of the database to store transients. So how does that get set to true? Time to explore how WP sets up its own cache API.

You can trace almost everything to wp-load.php or wp-settings.php -- both of which are crucial to the bootstrap process of WordPress. In our cache, there are some relevant lines in wp-settings.php.

// Start the WordPress object cache, or an external object cache if the drop-in is present.
wp_start_object_cache();

Remember that drop in thing from above? Let's take a look at wp_start_object_cache in wp-includes/load.php.

if object-cache.php exist in your content directory it gets included and WP assumes you're using an external, persistent cache -- it sets $_wp_using_ext_object_cache to true.

If you're using an external object cache transients will use it. Which brings up the question of when to use options vs. transients.

Simple. If you need data to persist indefinitely, use options. They get "cached", but their canonical sources is the database and they will never go away unless a user explicitly requests it.

For data that should be stored for a set amount of time, but does not need to persist beyond a specified lifetime use transients. Internally, WP will try to use an external, persistent object cache if it can otherwise data will go into the options table and get garbage collected via WordPress' psuedo-cron when they expire.

Some other concerns/questions:

Is it okay to do a ton of calls to get_option? Probably. They incur the call to a function overhead, but it likely won't hit the database. Database load is often a bigger concern in web application scalability than the work your language of choice does generating a page.

How do I know to use transients vs. the Cache API? If you expect data to persist for a set period, use the transient API. If it doesn't matter if data persists (eg. it doesn't take long to compute/fetch the data, but it shouldn't happen more than once per page load) use the cache API.

Are all options really cached on every pageload? Not necessarily. If you call add_option with its last, optional argument as no they are not autoloaded. That said, once you fetch them once, they go into the cache and subsequent calls won't hit the database.

nitpick 1: Not all options are loaded on page start, but only those that are marked "autoload=yes" when created. The default for that parameter in add_option is 'yes' and most plugin writers don't bother to understand the difference in using a 'no' there make your statement practically true.
–
Mark KaplunDec 3 '12 at 5:32

Trivial - It is always on and takes affect before any other caching comes into play. It stores the cached items in an php array which means that it consumes memory from your php execution session, and that the cache is emptied after php execution is over. i.e. even without using any other cache if you call get_option('opt') twice in a row you will make a DB query only the first time and the second time the value will be returned from memory.

File - Cached values are stored in files somewhere under your root directory. I believe it proved to be not effective in terms of performance unless you have a very fast disk or memory mapped file storage.

APC (or other php accelerator based caching) - Cached values are stored in the memory of your host machine and outside of your php memory allocation. The biggest potential pitiful is that there is no scoping of data and if you run two sites potentially each can access the cached data of the other, or overwrite it.

Memcahce - it is a network based cache. You can run the caching service anywhere on the network and It probably stores values in its host memory. You probably don't need memcache unless you have a load balancing in action.

BTW, object caching is caching much more then options, it will store almost anything that was retrieved from the DB using high level WP API.