Redis object caching is one of the most effective things you can do to a WordPress site, and one of the most frequently deployed where it does nothing at all. Both statements are true, and which one applies to you depends on facts about your traffic that are easy to check before you install anything.
What the object cache actually is
WordPress has had an object cache API since long before Redis was involved. During a page load, before running a database query, WordPress checks whether it already has the answer.
The important detail is the default backend. Out of the box the object cache is per request: it lives in PHP memory for the duration of one page load and is discarded when the request ends. It stops WordPress asking for the same option twice while building one page. It does nothing for the next visitor.
Dropping in Redis or Memcached makes it persistent. Cached results survive across requests, so a query run for one visitor can answer for the next.
That single word, persistent, is the whole feature. It also explains every case where it helps and every case where it does not: the benefit exists only when the same query is asked more than once, by different requests, within the cache lifetime.
Where it earns its keep
Sites doing real database work per page. A default WordPress blog post might run a few dozen queries. A WooCommerce category page with filters, or a membership site resolving access rules, or an install with forty plugins each fetching their own options can run many times that. When those queries repeat across visitors, persistent caching removes them.
Traffic volume. The benefit scales with how often the same query recurs before it expires. At a hundred requests an hour, most cached entries expire unused. At ten thousand, the cache is warm and nearly everything is a hit.
Pages that full-page caching cannot touch. This is the strongest case. A logged-in visitor, a cart, a member-only page, and a personalised dashboard all have to run PHP, and full-page caching is unavailable by definition. Redis cannot make the page static, but it can strip the repeated database work out of generating it. On a store where a meaningful share of traffic is logged in, this is where the wins are.
Autoloaded options. WordPress loads every autoloaded option on every request. On a site where plugins have accumulated a bloated wp_options table, that is a large query on the critical path of literally every page. Persistent caching removes the repetition, though the honest fix is to clean up what is being autoloaded.
Where it does not help
A site already served almost entirely from full-page cache. If anonymous visitors get prebuilt HTML, PHP never runs for them, so the object cache is never consulted. Adding Redis to a well-cached brochure site adds a service to run, monitor, and secure, in exchange for improving requests that were not happening. This is the most common misapplication.
Low traffic. Without repetition there is nothing to reuse.
Genuinely unique queries. If every request produces different results with no shared data, there is nothing to hit.
A slow database that is slow for other reasons. Caching in front of missing indexes or a badly written meta query hides the symptom for cached paths and leaves it in place for everything else. Fix the query, then cache it.
Measure before and after, with the right number
The number to watch is the hit ratio: the share of lookups answered from cache rather than falling through to the database.
A ratio below roughly 70 percent means something is wrong, and it is worth knowing which thing. The cache may still be cold, in which case it climbs on its own. Memory may be too small, so entries are evicted before they can be reused. Expiry times may be shorter than the interval between repeat requests. Or the site's query patterns genuinely do not repeat, which is a real answer and means Redis is not your problem.
Watch three things together, because any one alone misleads: hit ratio, memory used against memory allocated, and eviction count. A high hit ratio with heavy eviction means the cache is working and starved. WPMgr reports all three per site, so the question "did this help" has an answer rather than an opinion.
The other measurement worth taking is the one people skip: what the page cost before. If time to first byte was already 200ms, the database was not your bottleneck and nothing here will move it much.
Memory and eviction policy
Redis has a fixed memory ceiling. When it fills, the eviction policy decides what goes.
For a WordPress object cache, allkeys-lru is the sensible default: evict the least recently used key, whether or not it carries an expiry. This keeps hot data resident under pressure.
The policy to avoid is noeviction, which returns errors on write instead of making room. WordPress generally handles a failed cache write by carrying on and hitting the database, so the visible symptom is not an error page but a cache that silently stops accepting new entries and a hit ratio that decays while everything looks superficially fine.
volatile-lru only evicts keys with an expiry set, which sounds safer and behaves badly here, because WordPress sets many entries with no expiry at all. Under pressure it can find nothing eligible to evict.
Transients quietly become a different feature
WordPress transients are cached values with an expiry, and where they are stored depends entirely on whether a persistent object cache exists.
Without one, transients go in the wp_options table. They are rows in your database, they persist across requests because the database does, and expired ones are not reliably cleaned up, which is why wp_options on an older site is often full of stale transient rows.
Install a persistent object cache and transients move into it instead. Two consequences follow, and both surprise people.
The good one: the wp_options bloat stops accumulating, and transient reads stop being database queries. On sites where plugins lean heavily on transients this is a meaningful share of the benefit.
The one that causes support tickets: transients now evaporate when the cache is flushed or evicted. Code that stored something expensive in a transient and assumed it would survive because it always had now finds it gone. Anything written to survive a restart belongs in an option, not a transient. That was always true; a persistent object cache is just the thing that makes it visible.
Redis or Memcached
Both work. WordPress does not care which sits behind the drop-in.
Memcached is simpler, purely a volatile cache, and slightly faster for plain key lookups. Redis has richer data types, optional persistence to disk, and better introspection, which in practice means you can actually inspect what is cached and why the hit ratio is what it is.
For WordPress the deciding factor is usually availability: use whichever your host already runs well. Redis is the more common default now and the easier of the two to debug, which is why it is what most guidance, including this page, assumes.
Stale data and flushing
Caching introduces the possibility of serving something that is no longer true. WordPress handles most of this for you, invalidating relevant keys when posts and options change, and the common plugins do the same. The problems arise at the edges.
Code writing directly to the database with $wpdb bypasses the invalidation entirely, so the cache keeps returning the old value indefinitely. Imports, bulk edit scripts, and migrations frequently do this, which is why a bulk operation can appear to have done nothing until the cache is flushed.
The symptom is distinctive: changes that are correct in the database and wrong on the page, sometimes for some visitors and not others. If you see that, flush the cache before debugging anything else. If flushing fixes it, the bug is a missing invalidation, not the cache.
Worth knowing before an incident: flushing an object cache is safe. Nothing is lost that cannot be recomputed, the only cost is a period of slower requests while it warms again.
Two operational traps
Redis reachable from outside. Redis is not designed to sit on the public internet. It should bind to localhost or a private network, require a password, and never be exposed. A publicly reachable instance with no auth is a well-known and heavily scanned target, and on a shared host it may also be visible to other tenants.
One Redis, many sites, one keyspace. Pointing several WordPress installs at the same Redis without separating them means one site can read and flush another's entries. Use a distinct database index or key prefix per site. This bites agencies specifically, and it presents as impossible-to-reproduce bugs where clearing the cache on one client's site changes another's.
Layer it with full-page caching
These solve different problems and the strongest setup uses both:
- Full-page caching serves anonymous traffic without executing PHP at all. Largest single win for most sites.
- Object caching reduces the cost of everything that must execute PHP: logged-in sessions, carts, checkout, admin.
Configure page caching first and measure. Then, if a meaningful share of your traffic is authenticated or otherwise uncacheable, add object caching for that share and watch the hit ratio confirm it.
WPMgr runs both on the same site. Page caching lives in the Performance settings, and the object cache is a per-site toggle that connects to Redis and installs the drop-in for you, with hit ratio, memory, and latency reported back so the decision to keep it is based on your numbers.
See the Redis Object Cache feature page and the speed up WordPress guide.