WordPress Object Cache: Benchmarking Redis vs Memcached

by Sarah Mitchell
WordPress Object Cache: Benchmarking Redis vs Memcached

WordPress Object Cache: Benchmarking Redis vs Memcached

WordPress object cache is one of those settings that hosting sales pages mention prominently and site owners rarely verify. The promise is straightforward: instead of hitting MySQL for the same query on every page load, the result gets stored in memory and served from there. The reality is more nuanced — the backend you choose, the WordPress plugin bridging it, and how your host exposes the service all affect whether you see a 10 ms improvement or a 500 ms one.

This article benchmarks Redis and Memcached against each other on the same WordPress install, using the same content, the same traffic pattern, and the same measurement tooling. The goal is a number you can compare against your own site, not a general endorsement of either technology.

The Problem: Database Queries That Repeat on Every Request

On a stock WordPress install with no persistent object cache, the transient API and the WP_Object_Cache class store data in PHP memory for the duration of a single request. The moment that request ends, everything is discarded. The next visitor triggers the same queries again.

Running SHOW STATUS LIKE 'Questions' on a WooCommerce staging site with 800 products and no object cache showed 1,847 queries per page load on the shop archive. With a warm Redis cache in place, the same page dropped to 214 queries — an 88 % reduction. That query count is the upstream cause of slow TTFB; the cache is the lever that changes it.

Test Environment and Methodology

All tests ran on a VPS with 4 vCPUs and 8 GB RAM (Ubuntu 22.04), running Nginx 1.24, PHP 8.2-FPM with OPcache enabled, and MySQL 8.0. WordPress 6.5 was installed with WooCommerce 8.9 and 25 additional plugins representing a typical agency build (SEO, forms, membership, analytics).

Object cache drivers tested:

  • Redis 7.2 via the Redis Object Cache plugin (version 2.5.4) by Till Krüss
  • Memcached 1.6.23 via the WP Memcached drop-in (version 4.0.0)
  • No persistent cache (baseline)

Measurement tools:

  • k6 load test: 50 virtual users, 3-minute sustained run, cached and uncached URLs
  • Cloudflare Observatory (server-side TTFB, no CDN in front)
  • MySQL slow query log (threshold 0.01 s) for query volume
  • redis-cli INFO stats and memcached-tool stats for hit-rate verification

Each scenario ran three times; the median value is reported. Page cache (FastCGI or full-page) was disabled throughout so the object cache results are isolated. Enabling a page cache on top of an object cache is the correct production setup, but mixing both variables in one test makes it impossible to attribute gains.

Results: TTFB and Query Load Under 50 Concurrent Users

Scenario Median TTFB p95 TTFB MySQL Queries / Request Cache Hit Rate
No object cache 620 ms 1,140 ms 1,847
Memcached 1.6.23 188 ms 390 ms 231 91.4 %
Redis 7.2 (default config) 112 ms 224 ms 214 94.7 %
Redis 7.2 (persistent connections) 84 ms 163 ms 214 94.7 %

The baseline → Redis (persistent) improvement is a 620 ms → 84 ms TTFB reduction, or roughly 86 %. Memcached is a meaningful improvement over no cache, but Redis outperformed it on every metric in this configuration.

The difference between Redis default and Redis with persistent connections is worth isolating: without REDIS_PERSISTENT set to true in wp-config.php, PHP-FPM opens and closes a TCP connection to Redis on every request. At 50 concurrent users that overhead accumulates. Enabling persistent connections is a one-line config change with no downside on a single-server setup.

Why Redis Outperformed Memcached Here

Memcached's hit rate (91.4 %) trailed Redis (94.7 %) for a specific reason: WooCommerce stores some object groups — wc_session_id, wc_cart, counts — that benefit from atomic increment operations and key expiration precision. Redis supports both natively. The WP Memcached drop-in handles these groups but falls back to serialized string storage, which adds a small deserialization cost per read and occasionally causes stale counts under concurrent writes.

Memcached also has a hard limit on key length (250 bytes). WordPress generates object cache keys using a combination of blog ID, group, and key string. On a multisite install, those keys can exceed 250 bytes, causing silent cache misses. Redis has no practical key-length limit.

None of this means Memcached is a poor choice. On a single-site install with lighter plugin load, the gap narrows. If your host provides Memcached but not Redis, Memcached still cuts TTFB significantly compared to no persistent cache.

How Managed WordPress Hosts Expose Object Cache

Most managed WordPress hosts include an object cache backend, but the implementation details vary enough to affect your results.

Host type Typical backend Persistent connections default Multisite support Notes
Shared managed WP Memcached (shared pool) No Limited Key collisions possible between accounts
Premium managed WP Redis (dedicated instance) Yes Full Some hosts pre-install the drop-in
VPS / cloud (self-managed) Your choice Configurable Full Most control, most responsibility
Budget shared hosting None N/A N/A Object cache unavailable

The "shared pool" row is worth examining carefully. On some shared managed hosts, Memcached runs as a single instance shared across multiple customer accounts. Cache keys are namespaced by blog ID, but if the pool fills up and eviction happens, your site's cached objects compete with every other tenant's. This shows up as an unexpectedly low hit rate (sometimes below 70 %) even with the plugin correctly installed.

If you're on a host that offers Redis with a dedicated instance per account, you avoid that problem entirely. When evaluating hosting terbaik untuk website traffic tinggi, asking "is the Redis instance dedicated or shared?" is a more useful question than asking about raw server specs.

Recommended Configuration for Redis on WordPress

Once Redis is available on your server or host, the following settings produce the results shown in the benchmark above.

1. Install and activate the Redis Object Cache plugin Use the Till Krüss plugin (slug: redis-cache). It is the most actively maintained drop-in and the one most managed hosts test against.

2. Add to wp-config.php above the /* That's all */ line:

define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_PERSISTENT', true );
define( 'WP_REDIS_MAXTTL', 86400 );      // 24 hours, adjust per site
define( 'WP_REDIS_SELECTIVE_FLUSH', true ); // avoids full flush on post save

3. Verify the connection and hit rate In wp-admin under Settings → Redis, the plugin shows connection status and a real-time hit ratio. A healthy site should show above 85 % within 10–15 minutes of normal traffic. If you see below 70 %, check whether another plugin is calling wp_cache_flush() on every request (a known issue with some security plugins).

4. Exclude sessions from the object cache if running WooCommerce Some WooCommerce session handlers write large session blobs to the object cache, which can evict more valuable cached query results. Add this to wp-config.php:

define( 'WP_REDIS_IGNORED_GROUPS', ['wc_session_id'] );

Test with and without this exclusion; on high-traffic stores it consistently improves hit rate by 2–4 percentage points.

5. Set a Redis maxmemory-policy in redis.conf The default policy is noeviction, which causes Redis to return errors when memory is full rather than evicting old keys. For a WordPress object cache, allkeys-lru is the correct policy — it evicts the least recently used keys when memory pressure occurs, which degrades gracefully instead of breaking the site.

maxmemory 256mb
maxmemory-policy allkeys-lru

256 MB is sufficient for most single-site installs. Monitor actual usage with redis-cli INFO memory and adjust.

Do This First: A Prioritized Checklist

If you are starting from no persistent object cache, the order of operations matters. Each step builds on the last, and jumping ahead skips verification points that catch misconfiguration early.

  1. Confirm Redis or Memcached is available — run redis-cli ping or php -r "new Memcached();" before installing any plugin. A plugin that cannot reach the backend fails silently and leaves you on the baseline.

  2. Install the drop-in plugin and verify the connection — check wp-admin before touching any other setting.

  3. Run a baseline TTFB measurement — use curl -o /dev/null -s -w "%{time_starttransfer}" https://yoursite.com/shop/ three times and record the median. This is your before number.

  4. Enable persistent connections — add WP_REDIS_PERSISTENT and re-run the TTFB measurement. This single change produced a 25 % additional improvement in the benchmark above.

  5. Set maxmemory-policy allkeys-lru — if you control the Redis config. Skip this if you're on a managed host where Redis is pre-configured.

  6. Monitor hit rate for 48 hours — a hit rate that starts high and drifts down points to a memory or eviction problem. A hit rate that stays low from the start points to a plugin conflict.

  7. Layer a page cache on top — once object cache is stable and verified, add FastCGI page cache or a full-page caching plugin. The object cache handles authenticated users and dynamic queries; the page cache handles anonymous traffic. Both together produce the best results.

What the Numbers Mean for Hosting Decisions

The benchmark results reframe how to evaluate managed WordPress hosting. A host that includes Redis with a dedicated instance and persistent connections enabled by default is delivering something measurably different from one that offers shared Memcached or no persistent cache at all. The 620 ms → 84 ms TTFB gap in this test translates directly to Core Web Vitals: LCP on a server-rendered WooCommerce page is largely gated by TTFB, and an 84 ms TTFB gives the browser far more time budget to paint the largest contentful element within the 2.5-second threshold.

Before accepting a hosting provider's claim that they include "advanced caching," ask for the specific backend, whether the instance is dedicated, and whether persistent connections are enabled. Those three questions will tell you more than any marketing comparison chart.

The WordPress object cache is not a set-and-forget feature. Hit rate, memory usage, and eviction events need periodic review — especially after major plugin updates that change query patterns. The tooling is free, the configuration is minimal, and the before-to-after improvement is among the largest single-lever gains available in cara mengatasi lupa password WordPress admin and WordPress performance work.