wppaste
WordPress

wp_cache_set( int|string $key, mixed $data, string $group = '', int $expire = 0 ): bool

Since
2.0.0
Source
wp-includes/cache.php:108

Stores a value in the WordPress object cache under a given key and group, always overwriting any existing entry. Unlike wp_cache_add() it does not check whether the key already exists, so it is the right call when you want the newest value to win. Without a persistent object cache plugin the data only lives for the current request, and the $expire argument is honored only by backends that support expiration.

Saves the data to the cache.

Description

Differs from wp_cache_add() and wp_cache_replace() in that it will always write data.

Compatibility

WordPress
since 2.0.0
PHP
7.4–8.6-dev
  • 6.7.7
  • 6.8.8
  • 6.9.7
  • 7.0.4
  • 7.1.0

Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.

Parameters

$keyint|string
The cache key to use for retrieval later.
$datamixed
The contents to store in the cache.
$groupstringoptional
Where to group the cache contents. Enables the same key to be used across groups. Default empty.Default: ''
$expireintoptional
When to expire the cache contents, in seconds.
Default 0 (no expiration).Default: 0

Return value

bool
True on success, false on failure.

Code examples

Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.

Cache the result of an expensive post query for a limited time

Avoid recomputing a list of post titles on every load by checking the cache first and filling it with wp_cache_set() when it's empty.

$cache_key = 'five_recent_titles';
$cache_group = 'reference_demo';

$titles = wp_cache_get( $cache_key, $cache_group );

if ( false === $titles ) {
	$recent_posts = get_posts(
		array(
			'numberposts' => 5,
			'orderby'     => 'ID',
			'order'       => 'ASC',
		)
	);

	$titles = wp_list_pluck( $recent_posts, 'post_title' );

	wp_cache_set( $cache_key, $titles, $cache_group, 300 );

	echo 'Computed and cached: ';
} else {
	echo 'Read from cache: ';
}

print_r( $titles );

In the sandbox's default non-persistent cache the stored value only survives for the rest of this same request, so a page reload will always recompute it unless a persistent object cache is active.

Overwrite a cached counter regardless of whether it already exists

Show that wp_cache_set() always writes, so a second call replaces the first value instead of leaving it alone.

$key = 'homepage_hits';
$group = 'reference_demo';

wp_cache_set( $key, 10, $group );
echo 'After first set: ' . esc_html( wp_cache_get( $key, $group ) ) . '<br>';

wp_cache_set( $key, 25, $group );
echo 'After second set: ' . esc_html( wp_cache_get( $key, $group ) );

Common problems and fixes · 4

Why does my cached value disappear on the next page load?

The source calls the global $wp_object_cache, and WordPress's built-in object cache is non-persistent by default: it only lives for the current request and is rebuilt from scratch on the next one. - Install a persistent object cache drop-in (Redis, Memcached, etc.) if you need the value to survive across requests. - Otherwise treat wp_cache_set() as a per-request memoization tool, not long-term storage.

Why isn't the $expire time actually expiring my cached data?

wp_cache_set() casts $expire to an int and passes it straight to WP_Object_Cache::set(), but whether expiration is enforced at all depends on the caching backend in use, and the default non-persistent cache does not track wall-clock time the way a real cache server does. - Use set_transient() instead when you need guaranteed expiration without a persistent object cache.

Should I use wp_cache_set() or wp_cache_add() to save data?

wp_cache_set() always writes and silently overwrites any existing entry under that key and group, per the source. Use wp_cache_add() instead when you only want to write once and never clobber a value another part of the code may have already stored.

I set a value with an empty group, why does it clash with another plugin's key?

The $group argument defaults to an empty string, and the point of a group is to let the same key be reused without collisions across different parts of the codebase. - Always pass a distinct, plugin-specific $group string when calling wp_cache_set().

Alternatives and related functions

wp_cache_add
When you want to write a value only if that key doesn't already exist in the group, without overwriting an existing entry.
wp_cache_replace
When you want to update a value only if the key already exists, and do nothing if it doesn't.
wp_cache_get
When you need to read back a value that was previously stored with wp_cache_set().
set_transient
When you need the cached value to reliably survive across requests without depending on a persistent object cache plugin.

Performance profile

How much work a call to wp_cache_set() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.

Cost class
Trivial

Only touches the object cache, via wp_cache_set().

Scaling
Constant

No loop in the body: the same number of instructions runs whatever you pass in.

Instructions
13

Executed per call on PHP 8.5. The body compiles to 13.

Plugin surface
None

Nothing here hands control to plugin code.

Called by
42

42 places in core call this, so the cost is paid more often than your own code shows.

What it touches

  • cacheobject cachewp_cache_set()this function does it

What one call costs · 1 distinct outcome

One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_cache_set() can have, taken from its control-flow graph on PHP 8.5.

WhenInstructionsCalls it makes
always13->set()

Across PHP versions

Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 13 instructions, 13 executed per call, 0 branches. The work does not change between versions.

An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.

Used by · 42

Show all 42

Source code

function wp_cache_set( $key, $data, $group = '', $expire = 0 ) {	global $wp_object_cache; 	return $wp_object_cache->set( $key, $data, $group, (int) $expire );}

Changelog

Introduced in 2.0.0. Unchanged from 6.7.7 through 7.1.0.

  1. 6.7.7
  2. 6.8.8
  3. 6.9.7
  4. 7.0.4
  5. 7.1.0

Signature, return type and hooks compared across 5 parsed releases.

About this page

Parsed data
Generated from the wordpress-develop 7.1.0 tag, from src/wp-includes/cache.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.
Corrections
Something wrong on this page? Report it and it gets fixed in the next regeneration.