Building a Custom WordPress Object Cache Backend (Redis & Memcached Deep Dive)

Table of Contents

WordPress has a powerful but often overlooked feature: the Object Cache API.
By default, it works only per request — meaning all cached data is lost after the page finishes loading.

To unlock real performance gains, you need a persistent object cache using systems like Redis or Memcached.
In this guide, you’ll learn how to build your own custom backend step-by-step.

What is WordPress Object Cache?

The Object Cache stores query results and computed data in memory to avoid repeated expensive operations.

Core functions include:

  • wp_cache_get()
  • wp_cache_set()
  • wp_cache_delete()

Without a persistent backend, these only live during a single request.

How Persistent Object Cache Works

To enable persistence, WordPress looks for a file:

wp-content/object-cache.php

If present, it overrides the default cache system.

Step 1: Install Redis or Memcached

Redis Installation (Ubuntu)

Shell
sudo apt update
sudo apt install redis-server -y
sudo systemctl enable redis
sudo systemctl start redis

Memcached Installation

Shell
sudo apt install memcached libmemcached-tools -y
sudo systemctl enable memcached
sudo systemctl start memcached

Step 2: Install PHP Extensions

Redis PHP Extension

Shell
sudo apt install php-redis
sudo systemctl restart php-fpm

Memcached PHP Extension

Shell
sudo apt install php-memcached
sudo systemctl restart php-fpm

Step 3: Create Custom object-cache.php

Create this file:

wp-content/object-cache.php

Basic Structure

PHP
class WP_Object_Cache {

    private $cache = [];
    private $redis;

    public function __construct() {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }

    public function get( $key, $group = 'default' ) {
        $cache_key = $this->build_key($key, $group);

        $value = $this->redis->get($cache_key);

        if ($value !== false) {
            return unserialize($value);
        }

        return false;
    }

    public function set( $key, $data, $group = 'default', $expire = 0 ) {
        $cache_key = $this->build_key($key, $group);

        return $this->redis->setex(
            $cache_key,
            $expire ?: 3600,
            serialize($data)
        );
    }

    public function delete( $key, $group = 'default' ) {
        $cache_key = $this->build_key($key, $group);

        return $this->redis->del( $cache_key );
    }

    private function build_key( $key, $group ) {
        return "wp:" . $group . ":" . $key;
    }
}

Step 4: Hook Into WordPress Cache API

Expose functions expected by WordPress:

PHP
$GLOBALS['wp_object_cache'] = new \WP_Object_Cache();

function wp_cache_get($key, $group = '') {
    return $GLOBALS['wp_object_cache']->get($key, $group);
}

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

function wp_cache_delete( $key, $group = '' ) {
    return $GLOBALS['wp_object_cache']->delete( $key, $group );
}

Step 5: Test the Cache

PHP
\wp_cache_set( 'test_key', 'Hello Cache', 'custom', 60 );

$value = \wp_cache_get( 'test_key', 'custom' );

echo $value; // Should output: Hello Cache

Memcached Version (Alternative)

Replace Redis with Memcached:

PHP
$this->memcached = new \Memcached();
$this->memcached->addServer('127.0.0.1', 11211);

Set and get:

PHP
$this->memcached->set( $cache_key, $data, $expire );
$data = $this->memcached->get( $cache_key );

Performance Best Practices

  • Use short expiration times for dynamic data
  • Use groups to organize cache
  • Avoid caching extremely large objects
  • Use persistent connections

Common Pitfalls

  • Forgetting serialization
  • Key collisions between plugins
  • No cache invalidation strategy
  • Overusing cache for non-expensive operations

Advanced: Cache Invalidation

Always clear cache when data changes:

PHP
\add_action('save_post', function( $post_id ) {
    \wp_cache_delete( 'post_' . $post_id, 'posts' );
});

FAQ

Is Redis better than Memcached?

Redis supports persistence and advanced data types. Memcached is simpler and faster for basic caching.

Do I need object caching on small sites?

Not necessarily, but it helps as traffic grows.

Can object cache break my site?

Yes, if not implemented correctly — especially with stale data.

What is the biggest benefit?

Reducing database queries and improving response time (TTFB).

Should I use a plugin instead?

Plugins are easier, but custom implementations give full control and optimization.

Final Thoughts

Building a custom WordPress object cache backend gives you deep control over performance.

Whether you use Redis or Memcached, the key is understanding how WordPress interacts with cached data.

With proper implementation, you can dramatically reduce database load and improve scalability.

← How to Write High-Performance WordPress Plugins Without Killing TTFB WordPress Security Deep Dive: wp-json Exposure, Exploitable Endpoints & Hidden Login URLs →
Share this page
Back to top