A WordPress Redis object cache keeps the results of database queries and expensive lookups in memory between requests, so WordPress doesn’t rebuild them on every page load. Out of the box, WordPress caches objects only for the duration of one request. Adding Redis with an object-cache.php drop-in, usually through the Redis Object Cache plugin, makes that cache persistent. It helps most where page cache can’t: logged-in users, wp-admin, WooCommerce cart and checkout, the REST API and admin-ajax. It does little for anonymous visitors who already get cached HTML.
In audits, I see Redis treated as a speed switch: install it, flip it on, done. Sometimes it helps a lot. Sometimes the hit rate is poor, Redis is full and refusing writes, or two sites share one database and flush each other’s keys. This guide covers what the object cache actually does, how to set it up properly and how to check that it’s working. It is part of my guide on how to speed up WordPress.
What does the WordPress object cache do?
WordPress core has an object cache API: wp_cache_get(), wp_cache_set(), wp_cache_delete() and friends. Core uses it for posts, post meta, terms, users, options and query results. Plugins use it too, when they’re written well. The default implementation, WP_Object_Cache, stores everything in a PHP array that dies when the request ends. So within one page load, the second request for the same post is free. On the next page load, WordPress starts from zero.
When a file named object-cache.php exists in wp-content, WordPress loads it instead of the default implementation. That drop-in can send the same API calls to Redis or Memcached, and the data survives across requests and PHP workers. Transients change too: with a persistent object cache, set_transient() writes to the cache instead of the wp_options table, which takes some pressure off the database as well.
Object cache and page cache solve different problems, and people mix them up all the time. I wrote a separate explainer on page cache, object cache and edge cache, and which one you actually need. The short version:
| Request type | Served by page cache? | Does Redis help? |
|---|---|---|
| Anonymous visit to a cached page | Yes | Barely, PHP doesn’t run |
| Anonymous visit with a cache miss | No | Yes, fewer queries while the page is built |
| Logged-in user, wp-admin | No | Yes |
| WooCommerce cart, checkout, my account | No | Yes |
| REST API, admin-ajax, cron | Usually not | Yes |
When is a Redis object cache worth it?
Site Health suggests a persistent object cache when it sees a site that is large enough to benefit, for example by number of posts, users or options. That’s a reasonable signal. My own rule is simpler: if a meaningful share of your traffic can’t be served from page cache, you want one. That covers stores, membership sites, LMS platforms, forums, intranets and any site where editors spend hours in wp-admin.
A brochure site with five pages and full page caching will hardly notice it. It also won’t fix a plugin that runs a slow uncached query on every request, or a 3 MB block of autoloaded options. Redis stores what WordPress asks it to store. If the code bypasses the cache API, Redis never sees that work. For the autoload problem, see wp_options autoload and database optimization.
How do you set up Redis object cache in WordPress?
On managed hosting, check the panel first. Many hosts offer Redis as a toggle and already provide the drop-in, so installing a second one will just conflict. On your own server, the steps are:
- Install Redis server and a PHP client. The PhpRedis extension is a compiled C extension and is what I use when I control the server. Predis is a pure PHP library and works without one.
- Confirm Redis answers with
redis-cli ping, which should returnPONG. - Add the connection constants to
wp-config.php, above the line that says to stop editing. - Install the Redis Object Cache plugin and enable the drop-in, from its settings screen or with WP-CLI.
- Check the status and watch the hit rate for a day before you call it done.
A typical wp-config.php block looks like this. Host, port and password depend on your server, and a Unix socket works too:
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
// define( 'WP_REDIS_PASSWORD', 'set-this-on-the-server' );
define( 'WP_REDIS_DATABASE', 0 );
define( 'WP_REDIS_PREFIX', 'example_com:' );
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );Then enable and check it:
wp plugin install redis-cache --activate
wp redis enable
wp redis statusThe prefix is the setting people skip and later regret. If several WordPress installs share one Redis instance and none of them sets a prefix or a separate database, their keys can collide. Give every site its own prefix. The plugin’s documentation lists the other constants, including the one for choosing the client and the ones for TLS and clusters.
How should Redis itself be configured?
Two directives in redis.conf matter most for a cache: maxmemory and maxmemory-policy. Redis’s default policy is noeviction, which means that when memory is full, writes fail. For a WordPress object cache, where every key can be rebuilt from the database, you want Redis to evict old keys instead.
# redis.conf
maxmemory 256mb
maxmemory-policy allkeys-lruThe 256 MB there is a placeholder. The right size depends on how much data your site caches, and you find it by watching memory use after a few days of normal traffic. If used_memory sits at the limit and evictions keep climbing, the cache is too small for the working set. Also, keep Redis bound to localhost or a private network. An open Redis port on the internet is a security incident waiting to happen.
How do you know the object cache is working?
“Connected” in the plugin screen only proves WordPress can reach Redis. It says nothing about whether the cache helps. I check three things:
- Hit rate. Query Monitor shows object cache hits and misses for each request. On a warm cache, most lookups should be hits. On the server,
redis-cli info statsgiveskeyspace_hitsandkeyspace_missesfor the whole instance. - Query count. Compare the number of database queries on the same logged-in page with the drop-in enabled and disabled. It should drop clearly.
- Evictions and memory.
redis-cli info memoryand theevicted_keyscounter ininfo statstell you whether the cache is big enough.
redis-cli info stats | grep -E 'keyspace_(hits|misses)|evicted_keys'
redis-cli info memory | grep -E 'used_memory_human|maxmemory_human'Then measure what users feel. For logged-in and checkout pages, compare server response time before and after on the same URLs. My notes on reducing TTFB in WordPress cover how to measure it from the command line and in field data.
What goes wrong with Redis on WordPress?
These are the problems I find most often, roughly in order:
- Two drop-ins fighting. A caching plugin, the host and the Redis plugin each want to own
object-cache.php. Only one file can exist. Pick one and disable object caching in the others. - Redis full with
noeviction. Writes fail, and depending on the client, you get errors or a cache that silently stops updating. - Shared instance without prefixes. Staging and production on the same Redis, same database, no prefix. A flush on staging empties production’s cache.
- Plugins that flush the whole cache. Some call
wp_cache_flush()on every save or every cron run, so the hit rate never gets a chance to climb. Query Monitor or a quick search through plugin code forwp_cache_flushfinds them. - Redis on a different server with high latency. Each lookup is a network round trip. Hundreds of them per request add up. Keep Redis close to PHP.
- Stale data after direct database edits. If you change rows with SQL, the cache still holds the old values. Run
wp cache flushafterwards.
Redis or Memcached?
Both work as WordPress object cache backends through a drop-in. For this use case the difference matters less than the setup around it. Redis has richer data types, optional persistence to disk and good tooling, and most WordPress hosts and plugins support it, so it’s my default. Memcached is simpler and also does the job. If your host already runs one of them well, use that one. Whichever you pick, it should be close to PHP, sized for your data and evicting instead of failing when it fills up.
The object cache sits next to PHP itself in the server stack. If logged-in pages are still slow with a good hit rate, the next place to look is the PHP layer: worker counts and OPcache, covered in PHP-FPM and OPcache tuning for WordPress.
Frequently asked questions
Does Redis object cache replace a page cache plugin?
No. Page cache stores the finished HTML and skips PHP entirely. Object cache stores pieces of data while PHP is building the page. Most sites with dynamic traffic need both.
Is it safe to flush the Redis cache?
Yes, everything in it can be rebuilt from the database. Expect slower responses for a short while as the cache warms up again. On a shared instance, make sure the flush only touches your site’s keys or database.
Will Redis improve my Core Web Vitals?
Only through server response time, and only on requests that aren’t page cached. A faster TTFB leaves more of the 2.5 second LCP budget for the rest of the page. If your slow pages are already cached, look at the front end instead.
If your store or membership site is slow for logged-in users and you’d like someone to find where the time goes, from object cache to queries to PHP workers, that is what my WordPress performance audit covers.