Type something to search...
How to Set Up Object Caching with Redis in WordPress?

How to Set Up Object Caching with Redis in WordPress?

Every WordPress request runs dozens, sometimes hundreds, of database queries: fetching post content, checking options, resolving menus, looking up user meta. Object caching stores the results of those queries in memory, keyed so identical queries can be answered instantly on the next request instead of hitting MySQL again. WordPress actually has a basic object cache built in already, but by default it's non-persistent, meaning it only lives for the duration of a single page load and is thrown away the moment that request finishes, giving you no benefit across requests at all.

Redis, an in-memory data store, fixes exactly that gap. Installed alongside WordPress with a small connector plugin, it turns WordPress's built-in but non-persistent object cache into a genuinely persistent one that survives across requests, dramatically reducing database load, especially on pages with logged-in users, complex queries, or plugins that don't already play well with full-page caching. This guide covers installing Redis, wiring it into WordPress, and using the underlying cache API directly in your own code.

Persistent vs. Non-Persistent Object Caching

This distinction is the whole reason Redis is worth setting up, so it's worth being precise about it:

  • Non-persistent (WordPress's default) stores cached data only in PHP's memory for the lifetime of a single request. It still helps avoid running the exact same query twice within one page load, but the cache is gone the instant that request finishes, offering zero benefit to the next visitor.
  • Persistent (with Redis or Memcached) stores cached data in a separate, long-running process that survives across requests entirely. The next visitor requesting the same data gets it straight from memory, with no database query at all, until the cache entry is explicitly invalidated or expires.

This is also why object caching is distinct from page caching: page caching skips running PHP altogether for cached pages, which doesn't help logged-in users, WooCommerce carts, or any page excluded from full-page caching. A persistent object cache still speeds those pages up significantly, since the expensive database queries behind them get cached even when the full HTML output can't be.

Step 1: Install Redis on the Server

If you have SSH access to your server (a VPS or dedicated server; most standard shared hosting won't allow this), install Redis directly:

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install redis-server

# Confirm it's running
sudo systemctl status redis-server

By default, Redis listens on 127.0.0.1:6379, which is exactly what you want for a single-server WordPress setup, since it should only ever be reachable from the same machine, never exposed publicly. If you're on managed WordPress hosting, check your host's documentation first, many managed hosts (Kinsta, WP Engine, Cloudways) provide Redis as a one-click add-on rather than requiring you to install it yourself.

Verify Redis is responding:

redis-cli ping

A correctly running instance replies:

PONG

Step 2: Install a Redis Object Cache Plugin

WordPress needs a "drop-in" (a special file placed directly in wp-content/, outside the normal plugin loading system, so it can run before most of WordPress even initializes) to actually route its internal cache calls to Redis instead of the default non-persistent cache. The Redis Object Cache plugin handles generating and installing this drop-in for you:

  1. Install and activate Redis Object Cache from the Plugins screen.
  2. Go to Settings → Redis, and click Enable Object Cache.

This copies object-cache.php into your wp-content/ directory, which is the actual mechanism that intercepts WordPress's cache functions and redirects them to Redis.

Step 3: Configure Connection Details in wp-config.php

Add your Redis connection details as constants in wp-config.php, above the line that reads /* That's all, stop editing! */:

define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );
define( 'WP_REDIS_DATABASE', 0 );

// If your Redis instance requires a password (recommended for anything
// beyond a strictly localhost-only setup):
define( 'WP_REDIS_PASSWORD', 'your-strong-redis-password' );

// Confirm WordPress's own object cache is enabled — this should already
// be true by default, but it's worth verifying explicitly.
define( 'WP_CACHE', true );

WP_REDIS_DATABASE is worth calling out specifically if you're running multiple WordPress sites against the same Redis server: Redis supports multiple numbered logical databases (0-15 by default), and giving each site its own number keeps their cached data fully isolated, so clearing one site's cache never touches another's.

Step 4: Verify the Connection

Back in Settings → Redis in your WordPress dashboard, you should now see a Status: Connected indicator along with live stats: hits, misses, and total keys stored. If it shows Not connected instead, double-check:

  • The host and port in wp-config.php match what Redis is actually listening on (redis-cli config get bind and redis-cli config get port confirm this from the server side).
  • Your PHP installation has either the redis (PhpRedis) or predis client library available; the plugin's status page tells you which one it detected.
  • If you set WP_REDIS_PASSWORD, confirm it matches Redis's own configured password in redis.conf (the requirepass directive).

You can also confirm from the command line directly, watching Redis receive commands in real time as you browse your site:

redis-cli monitor

Using the Object Cache API Directly in Your Own Code

Once Redis is wired in as the persistent backend, any code using WordPress's standard object cache functions automatically benefits, no extra work required. This matters because a huge amount of WordPress core and popular plugins already use these functions internally. But it's also worth knowing the API directly, since it lets you cache expensive operations in your own theme or plugin code:

function get_top_rated_products() {
    $cache_key   = 'top_rated_products';
    $cache_group = 'my_theme';

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

    if ( false === $products ) {
        // Cache miss — run the expensive query.
        $products = new WP_Query( [
            'post_type'      => 'product',
            'posts_per_page' => 10,
            'meta_key'       => 'average_rating',
            'orderby'        => 'meta_value_num',
            'order'          => 'DESC',
        ] );

        // Store for one hour.
        wp_cache_set( $cache_key, $products, $cache_group, HOUR_IN_SECONDS );
    }

    return $products;
}

A few details worth understanding:

  • wp_cache_get() returns false on a cache miss, which is why the check is false === $products rather than a loose empty() check, in case a legitimately empty (but valid) result was previously cached.
  • The cache group ('my_theme') namespaces your keys, so top_rated_products in your theme's group never collides with a key of the same name used by a plugin or WordPress core in a different group.
  • HOUR_IN_SECONDS is one of several WordPress time constants (MINUTE_IN_SECONDS, DAY_IN_SECONDS, WEEK_IN_SECONDS) that make expiry times self-documenting instead of a bare, unexplained number like 3600.

Invalidate the cache explicitly whenever the underlying data changes, rather than only relying on expiry:

add_action( 'save_post_product', function () {
    wp_cache_delete( 'top_rated_products', 'my_theme' );
} );

Which WordPress Data Actually Gets Cached

Redis object caching isn't limited to code you write yourself; a large amount of WordPress core already routes through the object cache automatically once persistence is enabled, including:

  • Post objects and post meta, fetched via get_post() and get_post_meta(), which are called constantly throughout a typical page load.
  • User meta and options, including the entire wp_options autoloaded options set, which WordPress loads on every single request regardless of what page is being served.
  • Term and taxonomy data, used every time categories or tags are displayed or queried against.
  • Transients, WordPress's own short-lived cache API (set_transient() / get_transient()), which automatically uses the persistent object cache instead of the database once Redis is active, avoiding a database write and read for every transient operation.

This is why enabling persistent object caching tends to produce a broad, site-wide reduction in database queries per request, not just an improvement to the specific code you deliberately optimize yourself.

Monitoring Redis From the Command Line

The WordPress dashboard status page is useful for a quick check, but for ongoing monitoring, redis-cli gives you a more direct view of what's actually happening inside Redis itself.

Check overall memory usage and key statistics:

redis-cli info memory
redis-cli info stats

info stats includes keyspace_hits and keyspace_misses, which together tell you your cache hit ratio directly from Redis's own counters, independent of what the WordPress plugin reports:

redis-cli info stats | grep keyspace
# keyspace_hits:284913
# keyspace_misses:19204

A hit ratio comfortably above 90% (hits divided by hits plus misses) after normal traffic has had time to warm the cache is a good sign the setup is working as intended. A persistently low ratio usually points to either a very short expiry time on your cached keys, or a site with unusually varied, hard-to-cache queries (heavy use of custom, dynamic WP_Query arguments that rarely repeat, for example).

Count how many keys WordPress has stored:

redis-cli dbsize

And, if you ever need to clear everything and start fresh (equivalent to clicking "Flush Cache" in the plugin's settings page):

redis-cli flushdb

Use flushdb rather than flushall unless you're certain no other application shares this Redis instance; flushall clears every numbered database, not just the one WordPress is using.

Setting Memory Limits and an Eviction Policy

By default, Redis has no memory limit configured, which means it will keep accepting new cached data until it runs out of system RAM entirely, potentially affecting other processes on the same server. For a production WordPress setup, configure both a maximum memory limit and an eviction policy in redis.conf:

maxmemory 256mb
maxmemory-policy allkeys-lru
  • maxmemory 256mb caps how much RAM Redis is allowed to use; adjust this based on your server's total available memory and whatever else runs alongside it.
  • allkeys-lru tells Redis that once it hits that limit, it should evict the Least Recently Used keys first to make room for new ones, which is the right policy for a pure object cache use case, since older, rarely-accessed cached data is exactly what you want removed first, rather than Redis simply refusing new writes or crashing.

Restart Redis after changing redis.conf for the new settings to take effect:

sudo systemctl restart redis-server

Frequently Asked Questions (FAQ) About Redis Object Caching in WordPress

To install Redis itself on the server, generally yes, unless your host provides it as a managed add-on (common with Kinsta, WP Engine, and Cloudways). The WordPress-side plugin setup and wp-config.php constants can be done through normal file access regardless.

Object caching stores individual database query results in memory but still runs PHP for every request. Some setups also use Redis for full-page caching (storing entire rendered HTML pages), which is a separate, distinct configuration — both can coexist, but they solve different problems, similar to the object-cache-vs-page-cache distinction covered above.

Both work well as persistent object cache backends and are supported by the same Redis Object Cache-style plugins (or Memcached-specific equivalents). Redis has a richer feature set (persistence to disk, more data structures) that most WordPress sites never need to use directly, but either is a substantial improvement over no persistent cache at all.

Enable Query Monitor (a free debugging plugin) and check the database query count and object cache hit ratio shown in its admin bar panel. A well-configured Redis setup typically shows a high cache hit ratio (often 90%+) after the cache has warmed up from normal site traffic.

Usually not for content-related caching, since WordPress invalidates relevant cache keys automatically when posts, options, or meta change. After a significant code change (a new plugin version, a theme update touching cached logic), it's still reasonable to click Flush Cache in the Redis Object Cache plugin settings as a precaution.

Yes. Use the WP_REDIS_DATABASE constant to assign each site its own numbered Redis database (0 through 15 by default), which keeps each site's cached keys fully isolated from the others, even though they share the same underlying Redis process.

A correctly configured Redis Object Cache plugin fails gracefully: WordPress falls back to its default non-persistent object cache and continues serving pages normally, just without the performance benefit, rather than causing errors or downtime. Check the plugin's connection status regularly so a silent failure doesn't go unnoticed for long.

Order doesn't matter functionally, since they operate independently, but if you're building out a full performance stack, page caching and a CDN tend to produce more immediately visible speed gains for anonymous visitors. Object caching's benefit is most pronounced on logged-in traffic, WooCommerce, and dynamic pages that can't be fully page-cached.

Conclusion

Object caching with Redis closes a gap that WordPress's default cache leaves wide open: without it, every single request rebuilds its cache from nothing, no matter how many times the exact same query has already run. Wiring in Redis turns that into genuine persistence across requests, which pays off most clearly on the traffic full-page caching can't help with directly, logged-in users, WooCommerce, membership sites, and any page with meaningfully dynamic content.

The setup itself is short: install Redis on the server, activate a connector plugin, add a handful of constants to wp-config.php, and confirm the connection status shows green. From there, WordPress core and most well-built plugins take advantage of it automatically, and the wp_cache_get() / wp_cache_set() API is there whenever you want to cache something in your own code deliberately.

Here are a few additional resources if you want to go deeper:

Tags :
Share :

Related Posts

Effortlessly Crafting Compelling WordPress Pages

Effortlessly Crafting Compelling WordPress Pages

As a website owner or content creator, having the ability to seamlessly add new pages to your WordPress site is crucial. Whether you're introducing a

Continue Reading
High Traffic Tips for WordPress Mastery 🚥

High Traffic Tips for WordPress Mastery 🚥

In our digital age, where online visibility is paramount, ensuring your WordPress site can handle surging traffic is crucial. Just like a finely-tune

Continue Reading
How Do I Change the WordPress Login URL?

How Do I Change the WordPress Login URL?

By default, every WordPress site's login page lives at the same predictable address: yoursite.com/wp-login.php (which also happens to redirect from

Continue Reading