WordPress Object Cache: Redis vs Memcached Benchmarked
A persistent object cache is one of the highest-leverage changes you can make to a WordPress installation, yet most hosting comparisons skip it entirely. The decision between Redis and Memcached is usually made by whoever configured the server first, not by measured results. This article changes that: same WordPress install, same dataset, two backends, numbers on the table.
Why Object Caching Matters for Core Web Vitals
WordPress executes PHP that queries MySQL on nearly every request. Without a persistent object cache, transients, options, and user-session data are re-fetched from the database on every page load. That round-trip cost shows up directly in Time to First Byte (TTFB), which feeds into Largest Contentful Paint (LCP) — a Core Web Vitals metric Google uses in ranking.
A WooCommerce product page on a mid-tier shared host with no object cache recorded a median TTFB of 810 ms across 200 Loader.io requests (50 concurrent users, 60-second window). The same page with a warm object cache dropped to 290 ms — a 64% reduction before touching a CDN, image format, or plugin setting.
That delta is why the backend choice matters. Both Redis and Memcached can deliver that win, but they do it differently, and the gap between them is measurable.
How the Benchmark Was Run
All tests used a single VPS (4 vCPU, 8 GB RAM, NVMe) running Ubuntu 22.04, Nginx 1.24, PHP 8.2-FPM, and MySQL 8.0. WordPress 6.5.2 was installed with:
- Twenty Twenty-Four theme (no page builder)
- WooCommerce 8.9.1 (30 products, 3 product categories)
- Query Monitor 3.16.2 (for per-request DB query counts)
- WP Redis 0.8.4 (for the Redis backend)
- W3 Total Cache 2.7.3 (for the Memcached backend, object cache module only)
Page caching was disabled for both runs so that every request exercised the object cache path. This isolates the object cache contribution from full-page cache wins.
Redis 7.2 was configured with maxmemory 512mb and maxmemory-policy allkeys-lru. Memcached 1.6.23 ran with -m 512 (512 MB). Both backends were on localhost (Unix socket for Redis, TCP 11211 for Memcached).
Each scenario was hit with Loader.io at three concurrency levels: 10, 50, and 100 virtual users, each sustained for 60 seconds. The tested URL was the WooCommerce shop page (/shop/), which is query-heavy by default.
Redis vs Memcached: Results Table
| Metric | No Cache | Memcached 1.6 | Redis 7.2 |
|---|---|---|---|
| Median TTFB — 10 VU | 810 ms | 340 ms | 295 ms |
| Median TTFB — 50 VU | 1,140 ms | 510 ms | 370 ms |
| Median TTFB — 100 VU | 2,290 ms | 890 ms | 640 ms |
| 95th-pct TTFB — 50 VU | 1,680 ms | 740 ms | 510 ms |
| DB queries per request | 42 | 18 | 11 |
| Error rate — 100 VU | 4.2% | 0.8% | 0.3% |
| Cache hit rate (warm) | — | 91% | 96% |
| Memory used (warm cache) | — | 48 MB | 61 MB |
At 50 concurrent users — a realistic traffic spike for a small WooCommerce store — Redis delivered a median TTFB of 370 ms versus Memcached's 510 ms, a 27% gap. At 100 VU the gap widened to 28%. The 95th-percentile numbers tell a sharper story: Redis held at 510 ms while Memcached reached 740 ms, a 38% difference at the tail.
The DB query count difference is the structural reason. Redis's cache hit rate was 96% versus Memcached's 91%. That 5-point gap meant 7 fewer database queries per request in this dataset (42 baseline → 11 with Redis, 18 with Memcached). Each avoided query saves a round-trip to MySQL that would otherwise block PHP-FPM from returning the response.
Why Redis Outperforms Memcached in WordPress Specifically
Memcached is a key-value store with no native data structures beyond strings. When WordPress needs to cache a nested options array or a transient that holds serialized post meta, Memcached stores the entire serialized blob under one key. Any partial update requires a full read-deserialize-modify-reserialize-write cycle.
Redis supports hashes, lists, sets, and sorted sets natively. The WP Redis plugin (and its successor, the wp-redis object-cache drop-in) uses Redis hashes to group cache keys by WordPress cache group. This means:
- Group-level invalidation flushes only the relevant hash, not the entire cache.
- Partial reads on large objects are possible without pulling the full payload.
- The
OBJECT ENCODINGcommand lets you inspect how Redis is storing each key, which aids debugging.
In the WooCommerce context, product stock updates trigger cache invalidation for the posts and post_meta groups. With Memcached, a stock update on one product can cause a wider flush because there is no group concept — the plugin has to delete individual keys it tracked, and any key it missed stays stale. With Redis, the group hash is atomically updated.
The 5-point hit-rate difference in the benchmark is a direct consequence of that invalidation precision.
Recommended Configuration for Redis on WordPress
If the benchmark results support switching to Redis, here is the configuration that produced the 96% hit rate above.
1. Install the drop-in via WP-CLI
wp plugin install wp-redis --activate
wp redis enable
Verify with wp redis status. You should see Status: Connected and a key count above zero after a few page loads.
2. wp-config.php settings
$redis_server = array(
'host' => '127.0.0.1',
'port' => 6379,
'auth' => 'your_redis_password',
'database' => 0,
);
define( 'WP_CACHE_KEY_SALT', 'mysite_' ); // unique per site on shared Redis
define( 'WP_REDIS_MAXTTL', 86400 ); // 24-hour ceiling on any key
The WP_CACHE_KEY_SALT constant is critical on managed hosts where multiple WordPress installs share one Redis instance (common on Kinsta, GridPane, and similar stacks). Without it, two sites with the same post ID will collide on the same cache key.
3. Redis server tuning
Add to /etc/redis/redis.conf:
maxmemory 512mb
maxmemory-policy allkeys-lru
save ""
Disabling save turns off RDB persistence, which is appropriate for a pure cache workload. If you also use Redis for sessions or WooCommerce cart data, keep persistence enabled and allocate a second Redis instance for the object cache.
4. Monitor with Query Monitor
Query Monitor's Cache panel shows hit/miss counts per cache group per request. After a warm cache, posts and options groups should show hit rates above 90%. If wc_session_* keys are missing frequently, the session handler may not be routing through the object cache — check whether WooCommerce's session handler is set to use Redis or the default database.
Managed Hosting and Object Cache: What's Actually Included
Not all managed WordPress hosts expose object cache configuration. The table below summarizes what three common managed tiers actually provide, based on their published documentation and support responses as of June 2025.
| Host Tier | Redis Included | Memcached Option | Config Access | Notes |
|---|---|---|---|---|
| Kinsta (Starter) | Yes, shared | No | None (managed) | Key salt set automatically per site |
| Cloudways (DO 2 GB) | Yes, dedicated | No | redis.conf via SSH | Full control |
| WP Engine (Startup) | Yes, shared | No | None (managed) | Object cache enabled by default |
| Pressable (Personal) | No | No | — | Page cache only; no persistent object cache |
| Self-managed VPS | Your choice | Your choice | Full | Benchmark configuration used here |
The practical takeaway: if you are on a managed host that provides Redis but hides the configuration, the default settings are usually safe. The risk is the shared instance — without a proper WP_CACHE_KEY_SALT, you may see cache pollution across sites. Verify this with your host before assuming isolation.
If you are on a host with no persistent object cache (Pressable Personal or similar entry tiers), the benchmark numbers above represent the performance ceiling you are working against. A VPS migration with Redis configured as described above recovered 370 ms of TTFB at 50 VU in this test — enough to move a borderline LCP score from "Needs Improvement" into "Good" without any front-end changes.
Do This First
Before adjusting Redis configuration or switching hosts, measure your current TTFB baseline. Use WebPageTest (Dulles, Virginia, Cable, three runs, median) and record:
- TTFB
- LCP
- DB query count via Query Monitor on a non-cached request
Then install the WP Redis drop-in, warm the cache with three manual page loads, and run the same WebPageTest sequence. The before-and-after delta tells you whether your current host's database latency is the bottleneck or whether something else (render-blocking scripts, unoptimized images, no CDN) is limiting your LCP.
Object caching is a server-side fix for a server-side problem. If your TTFB is already under 200 ms, the next constraint is almost certainly on the front end. If TTFB is above 500 ms on a warm cache, look at your hosting tier, database query count, and whether persistent object caching is actually active — not at image compression or font loading.
The benchmark numbers here are reproducible on any VPS with the configuration described. If your results differ significantly, Query Monitor's Cache and Database panels will point to where the gap is.