Skip to content

PerformanceUpdated 8 min read

WordPress Redis object cache: setup and measurement

Set up a WordPress Redis object cache, verify the drop-in, measure hit ratio and evictions, and diagnose slow or failing cache connections safely.

Portrait of Hamza Ahmad AslamBy AI & WordPress Developer | Speed Optimization & Site Security

A fast robotic arm grabs ready answer cards from a red-glowing memory shelf while the heavy database vault door stays shut.
Illustration generated with ChatGPT
On this page
  1. What a WordPress Redis object cache changes
  2. How to set up the Redis Object Cache plugin
  3. Configure the connection and key namespace
  4. Isolate shared Redis and multisite installations
  5. How to measure cache hits, misses, and memory
  6. How Redis evictions affect WordPress
  7. How non-persistent groups differ from plugin ignored groups
  8. How to tell when Redis is making WordPress slower
  9. What happens when Redis is unavailable
  10. What Redis changes for WooCommerce
  11. What to do next
  12. Frequently asked questions

Short answer: A WordPress Redis object cache keeps WordPress object-cache data available across requests, so PHP can reuse cached query results and other objects instead of rebuilding them each time. It helps most on requests that still execute WordPress, such as logged-in pages, wp-admin, WooCommerce flows, and uncached front-end requests.

What a WordPress Redis object cache changes

WordPress includes WP_Object_Cache, but the default implementation keeps cached objects only for the current request. WordPress documents that behavior in the WP_Object_Cache reference (opens in a new tab). A persistent object cache replaces that request-only storage with a backend that survives between requests.

WordPress loads a persistent cache through wp-content/object-cache.php. The Redis Object Cache plugin installs that object-cache.php drop-in and routes WordPress wp_cache_*() calls to Redis.

This is separate from full-page caching. A page cache can return stored HTML before WordPress runs. Redis helps after PHP and WordPress are involved, which is why it is most useful for admin screens, authenticated traffic, API requests, cart and checkout activity, and pages that miss the page cache.

A cache hit can avoid database work or repeated computation. A miss still has to build the value, then Redis can store it for later requests.

How to set up the Redis Object Cache plugin

The current Redis Object Cache project documentation (opens in a new tab) lists these WP-CLI commands:

wp redis enable
wp redis status
wp redis disable
wp redis update-dropin

wp redis enable enables the persistent object cache. wp redis status shows connection and drop-in diagnostics. wp redis disable disables it, and wp redis update-dropin refreshes the installed drop-in.

Run the status command after enabling Redis:

wp redis enable
wp redis status

Check that the plugin reports a connected Redis backend and a valid object-cache.php drop-in. If status reports that Redis is not connected, fix the Redis service, hostname, port, authentication, or socket path before measuring performance.

Configure the connection and key namespace

The plugin currently documents 127.0.0.1 as the default host, 6379 as the default port, database 0 as the default database, and one second for both connection and read/write timeouts.

A basic wp-config.php setup can look like this:

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

define( 'WP_REDIS_PREFIX', 'example-prod:' );

define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );

define( 'WP_REDIS_MAXTTL', 0 );

WP_REDIS_PREFIX is the current plugin setting for separating key namespaces. WP_REDIS_MAXTTL has a documented default of 0, which means the plugin does not impose a maximum TTL.

The plugin documentation now marks WP_CACHE_KEY_SALT as deprecated and says WP_REDIS_PREFIX replaces it. Do not add a new WP_CACHE_KEY_SALT for this plugin. If a legacy installation already uses one, plan the namespace change carefully because changing prefixes makes existing Redis keys unreachable to that site.

Isolate shared Redis and multisite installations

Every independent WordPress installation sharing a Redis service needs its own key namespace. Use a unique WP_REDIS_PREFIX for each installation. The plugin also supports selecting a Redis database with WP_REDIS_DATABASE where the Redis topology supports database selection.

On WordPress multisite, one network still needs a namespace that does not collide with another WordPress installation. WordPress object-cache APIs also distinguish global groups from site-specific groups, so do not try to create per-site prefixes manually inside plugin code.

How to measure cache hits, misses, and memory

Do not judge Redis only by whether wp redis status says "connected." Measure whether requests are reusing cached objects and whether Redis is under memory pressure.

Redis exposes the required counters through the INFO command (opens in a new tab).

Run:

redis-cli INFO stats
redis-cli INFO memory

If Redis is on another host:

redis-cli -h redis.internal -p 6379 INFO stats
redis-cli -h redis.internal -p 6379 INFO memory

For authenticated environments, use the authentication method required by that Redis deployment rather than placing secrets directly in shell history.

Example output from INFO stats might look like this. These values are illustrative:

keyspace_hits:1250400
keyspace_misses:246000
evicted_keys:3100
expired_keys:18422

Compute the cache hit ratio as:

hit ratio = keyspace_hits / (keyspace_hits + keyspace_misses) * 100

hit ratio = 1250400 / (1250400 + 246000) * 100
hit ratio = 83.6%

That percentage is only the result of this example. It is not a universal target. Compare the ratio before and after configuration changes, and compare it with page generation time, database query work, and Redis latency.

Example output from INFO memory might look like this:

used_memory:268435456
used_memory_human:256.00M
maxmemory:536870912
maxmemory_human:512.00M
maxmemory_policy:allkeys-lru

used_memory shows Redis-managed memory in use. maxmemory is the configured memory ceiling. maxmemory_policy reports the active eviction policy.

How Redis evictions affect WordPress

For a Redis instance used only as a cache, set a deliberate memory ceiling and an eviction policy that can remove cache entries when the limit is reached. Redis documents allkeys-lru as a cache configuration example in its Redis configuration guide (opens in a new tab).

A Redis configuration can include:

maxmemory 512mb
maxmemory-policy allkeys-lru

The memory size here is an example configuration value, not a recommendation for every site. Size the limit from the workload and available memory.

allkeys-lru makes all keys eligible for approximate least-recently-used eviction. That is a reasonable fit when the Redis instance contains disposable cache data only. Do not apply it blindly to a Redis server that also stores data that must never be evicted.

Watch evicted_keys in INFO stats. A rising value means Redis is removing keys because it reached the maxmemory limit. Occasional eviction can be normal for a bounded cache, but sustained growth can lower reuse and force WordPress to rebuild objects repeatedly.

If used_memory stays close to maxmemory, evicted_keys keeps climbing, and misses rise, the cache may be too small for the active working set.

How non-persistent groups differ from plugin ignored groups

WordPress provides wp_cache_add_non_persistent_groups() so code can mark groups that should not survive between requests. Core currently registers groups such as counts, plugins, and theme_json as non-persistent.

Plugin or theme code can register its own request-only group:

wp_cache_add_non_persistent_groups(
    array(
        'my_request_only_data',
    )
);

Use this only when the data is safe for the current request but should not be reused by later requests. Examples include values that depend on request-specific state that the cache key does not fully represent.

WP_REDIS_IGNORED_GROUPS is different. It is a Redis Object Cache plugin configuration constant. The plugin documents it as a list of groups that should not be cached between requests in Redis, with an empty array as the default.

The two mechanisms can produce similar persistence behavior with this plugin, but they are not the same API. wp_cache_add_non_persistent_groups() is the WordPress cache interface. WP_REDIS_IGNORED_GROUPS is plugin-specific configuration. Do not copy core groups into the plugin constant unless a specific compatibility case requires it.

How to tell when Redis is making WordPress slower

Redis can add time instead of removing it when each lookup costs more than the work it avoids.

A remote Redis server adds network round trips to object-cache calls. Measure that path from the WordPress host:

redis-cli -h redis.internal -p 6379 --latency

Example output might look like this:

min: 1, max: 4, avg: 1.62 (420 samples)

Redis documents --latency as repeated PING timing in milliseconds. This is not PHP application timing, but it helps reveal network delay between the WordPress host and Redis.

A low hit ratio is another warning. If many cache lookups miss, WordPress pays for the Redis request and still performs the database or computation work.

Large serialized values can also hurt. They cost transfer time plus PHP serialization or unserialization work. The alloptions object deserves special attention because WordPress loads and caches autoloaded options together. A very large autoloaded set can turn one cache lookup into a large payload on many requests. An autoloaded option rewritten on every request also replaces that cached copy each time, and the option-churn plugin finds such options by counting writes across many requests and naming the plugin, theme or core function that made them.

Frequent full cache flushes erase reuse. If hits fall sharply after deploys, imports, scheduled jobs, or plugin actions, look for code that flushes the entire object cache instead of invalidating only affected data.

What happens when Redis is unavailable

The Redis Object Cache 2.3.0 changelog says, "Throw errors when connection error occurs." The current documentation does not provide a transparent fallback that silently switches to the default WordPress cache after Redis fails.

Current Redis Object Cache documentation lists WP_REDIS_DISABLED as an emergency switch that bypasses the object cache without deleting the drop-in:

define( 'WP_REDIS_DISABLED', true );

The same documentation describes WP_REDIS_GRACEFUL as a setting that "Prevents exceptions from being thrown, but will cause data corruption." Do not use it as an automatic failover setting.

The practical failure plan is to keep Redis available where the site depends on it, monitor connection errors, and have a controlled way to set WP_REDIS_DISABLED during an outage. That lets WordPress run without the persistent Redis backend while the service is repaired.

Test this path before production incidents. Disable Redis in a staging environment, confirm WordPress still boots, then verify the application under the non-persistent object cache behavior.

What Redis changes for WooCommerce

WooCommerce's WC_Session_Handler has stored sessions in a custom database table since WooCommerce 2.5. The current WooCommerce WC_Session_Handler source (opens in a new tab) uses the WordPress table prefix plus woocommerce_sessions.

The session handler also caches each session row through the WordPress object-cache API under its session cache group. It reads the cached value with wp_cache_get() before querying the table, and uses wp_cache_add() or wp_cache_set() when caching session data.

With a persistent Redis object cache active, an active WooCommerce session can therefore be read from Redis while the custom session table remains the source of truth. Redis does not replace WooCommerce's session table.

Redis also helps a store because WooCommerce requests read many WordPress objects outside session storage. Products, metadata, options, users, terms, and plugin data can all involve object-cache lookups.

Cart, checkout, account, and admin requests often bypass full-page caching, so persistent object caching can matter more there than on a fully cached brochure page. Measure those request types separately instead of relying on homepage results.

What to do next

After Redis is connected, compare time to first byte on uncached and authenticated requests. If wp-admin remains slow, follow the slow WordPress admin guide.

If alloptions is large, measure ownership and autoload size with the WordPress autoloaded options guide. For site-wide profiling and remediation, use the WordPress performance optimization service.

Frequently asked questions

Does WordPress need Redis for object caching?

No. WordPress has an object cache without Redis, but the default cache lasts only for the current request. Redis is one way to make object-cache data persistent across requests.

Is Redis object cache the same as page cache?

No. A page cache stores complete responses such as HTML, while an object cache stores application data addressed by cache keys and groups. A request can use both layers.

What cache hit ratio should WordPress Redis have?

There is no universal percentage that proves the cache is healthy. Compare hits, misses, Redis latency, database work, and request time for the same workload, then watch how those values change after tuning.

Can WordPress keep working if Redis goes down?

The Redis Object Cache plugin provides WP_REDIS_DISABLED as an emergency bypass. Its documentation says WP_REDIS_GRACEFUL "Prevents exceptions from being thrown, but will cause data corruption," so it should not be treated as an automatic failover mechanism.

How this article was made: drafted with AI assistance from a researched brief, then checked against primary documentation before publishing.

Enjoyed this? Get the next article by email.

Occasional, useful posts. No spam, and you can unsubscribe anytime.

  • Every spillway of a dam opens at once and a glowing flood rushes toward a small mill below, while a lever on the dam waits to stagger the gates.Performance

    6 min read

    Why a cache purge can overload WordPress and how to stop it

    A WordPress cache stampede happens when many requests lose the same cached data at once and all try to rebuild it. The fix is to limit rebuilds with a shared lock, keep stale data available during refresh, and spread expiries so misses do not arrive as one burst.

    • WordPress
    • Caching
    • Performance
    Read article
  • A brass robotic arm working through a wall of pigeonholes stacked with task envelopes, a large calendar wheel turning overhead.Performance

    7 min read

    WooCommerce Action Scheduler: clear a backlog and keep it healthy

    A WooCommerce Action Scheduler backlog means scheduled background work is arriving faster than it is being processed, or processing has stopped. Start by grouping pending and failed actions by hook, fix the hook or cron problem, then drain the queue with WP-CLI instead of deleting unknown jobs.

    • WooCommerce
    • WP-CLI
    • Performance
    Read article
  • Small robotic carts carry order folders over a bridge from overflowing old filing cabinets into a bright, neatly indexed vault.Performance

    7 min read

    WooCommerce HPOS: migrate to High-Performance Order Storage safely

    WooCommerce HPOS moves core order data out of WordPress post storage into dedicated WooCommerce tables. Migrate safely by checking extension compatibility, synchronizing both data stores, verifying them, switching HPOS to authoritative, then testing every order workflow before you disable synchronization.

    • WooCommerce
    • Database
    • Performance
    Read article