WordPress Object Cache: Redis vs Memcached Benchmarked
Every uncached WordPress page load fires dozens of database queries. On a WooCommerce catalog page, that number routinely exceeds 80. A persistent object cache intercepts those repeat queries and serves results from memory instead — but the choice of backend matters more than most tutorials admit.
This piece puts Redis and Memcached through the same staging-to-production pipeline I ran at an agency managing 200+ sites. The metric that prompted the test: a client's TTFB sitting at 740 ms on a VPS with plenty of idle RAM and no object cache configured at all.
Why TTFB Is the Right Metric Here
Time to First Byte is the cleanest signal for server-side work. It strips out network variance, render time, and client-side JavaScript — leaving only how long the server spent building the response. For object cache testing, that isolation is exactly what you need.
LCP and Core Web Vitals matter for the full user experience, but if your TTFB is above 600 ms, you have a server problem that no amount of image optimization will fix. Google's own guidance flags anything above 800 ms as poor; the target is under 200 ms.
All measurements below were taken with curl timing templates (recording time_starttransfer) averaged over 50 cold-cache requests per configuration, with WordPress's built-in WP_DEBUG off and no page cache active. The goal was to isolate object cache behavior, not mask it behind a full-page cache layer.
Test Environment
- Server: Ubuntu 22.04 LTS, 4 vCPU, 8 GB RAM, NVMe SSD
- WordPress: 6.5.3
- PHP: 8.2 with OPcache enabled (128 MB)
- MySQL: 8.0, query cache disabled (deprecated and off by default)
- Theme: Storefront 4.5.0 with WooCommerce 8.9.1, 500 products
- Redis: 7.2.4, socket connection via
redis.sock - Memcached: 1.6.23, socket connection via
/tmp/memcached.sock - Object cache plugins: Redis Object Cache 2.5.2 (Till Krüss) and WP Memcached Object Cache 3.2.1
- Measurement tool:
curlwith--write-outtiming, 50 requests per config, median reported
Both cache backends used Unix domain sockets rather than TCP loopback to eliminate network stack overhead from the comparison.
Baseline: No Object Cache
With no object cache installed, the WooCommerce shop page averaged 742 ms TTFB across 50 requests. The MySQL slow query log showed 23 queries exceeding 10 ms, mostly wp_options autoload reads and product meta lookups.
Running EXPLAIN on the top offenders confirmed the usual suspects: repeated SELECT option_value FROM wp_options WHERE option_name = ? calls that WordPress does not batch by default, and WooCommerce session reads that hit the database on every request.
This is the problem object caching solves. The question is how much each backend solves it.
Redis vs Memcached: Head-to-Head Results
The table below shows median TTFB, p95 TTFB, and MySQL query count per page load across four configurations.
| Configuration | Median TTFB | p95 TTFB | DB Queries/Request |
|---|---|---|---|
| No object cache | 742 ms | 1,140 ms | 87 |
| Memcached (TCP) | 498 ms | 710 ms | 31 |
| Memcached (socket) | 461 ms | 638 ms | 31 |
| Redis (TCP) | 431 ms | 601 ms | 28 |
| Redis (socket) | 458 ms | 612 ms | 28 |
A result worth pausing on: Redis over TCP beat Redis over socket in median TTFB by 27 ms in this environment. That is within margin of variance across runs, but it did not flip on any of the five repeated test batches. The likely explanation is Redis 7's improved TCP handling and the fact that PHP's phpredis extension has more mature connection pooling over TCP than over socket in this PHP-FPM configuration. Memcached showed the more expected pattern where socket outperformed TCP.
The headline number: Redis (TCP) delivered a 419 ms TTFB — a 44% reduction from the 742 ms baseline. Memcached socket came in at 461 ms, a 38% reduction. Both are meaningful. Neither is negligible.
Where Redis Pulls Ahead
The query count difference (28 vs 31 per request) looks small, but it compounds under load. More important is which queries each backend eliminated.
Using the Query Monitor plugin (5.1.0) to inspect cache hit/miss logs, Redis achieved a 94.2% cache hit rate on wp_options reads versus Memcached's 91.7%. The gap traces to one architectural difference: Redis supports hash data structures natively. The Redis Object Cache plugin stores option groups as Redis hashes, meaning a single HGETALL command retrieves multiple options in one round trip. Memcached stores each key independently, so retrieving a group of options requires multiple GET commands.
For WooCommerce specifically, this matters. WooCommerce stores product attributes, tax rates, and shipping zones as option groups. Redis collapses those into fewer cache operations; Memcached cannot.
Where Memcached Still Makes Sense
Memcached has two genuine advantages that Redis does not match:
1. Memory efficiency for simple key-value workloads. Memcached's slab allocator wastes less memory on small string values than Redis's object encoding. If your WordPress site is primarily a blog or brochure site — not WooCommerce — and RAM is constrained below 512 MB, Memcached can serve more cached objects per megabyte.
2. Lower operational complexity on shared hosting. Several managed WordPress hosts expose Memcached as a one-click add-on because it has no persistence configuration to reason about. Redis on managed hosts often requires choosing between RDB snapshots, AOF logging, or no persistence — a decision that trips up developers who just want a cache.
If your host offers only Memcached, use it. A 38% TTFB reduction is not a consolation prize.
Recommended Redis Configuration for WordPress
The default Redis Object Cache plugin settings work, but three changes materially affect performance:
Set a maxmemory policy. Without one, Redis will refuse new writes when it hits the memory ceiling. For a cache-only deployment, set maxmemory-policy allkeys-lru in redis.conf. This evicts the least-recently-used keys when memory fills, which is the correct behavior for a WordPress object cache.
maxmemory 256mb
maxmemory-policy allkeys-lru
Use a dedicated Redis database index. If the same Redis instance serves other applications, assign WordPress to WP_REDIS_DATABASE 1 (or higher) in wp-config.php. This prevents key collisions without requiring a separate Redis process.
define( 'WP_REDIS_DATABASE', 1 );
Enable the drop-in, not just the plugin. The Redis Object Cache plugin must write object-cache.php to wp-content/. If you deploy via Git or rsync and that file gets overwritten, you lose the cache silently. Add a health check — the plugin's dashboard widget shows connection status, or you can query WP_Object_Cache::stats() programmatically in a mu-plugin.
Recommended Memcached Configuration for WordPress
For Memcached deployments, the equivalent tuning points are:
Set -m to a fixed allocation. Running Memcached without a memory cap lets it compete with PHP-FPM for RAM. A reasonable starting point on a 2 GB VPS is -m 256.
Increase the maximum object size if you cache large option values. WooCommerce product data can exceed Memcached's default 1 MB item limit. Add -I 2m to allow 2 MB items.
Use SASL authentication if Memcached is exposed beyond localhost. The default Memcached install listens on all interfaces with no authentication. Bind it to 127.0.0.1 explicitly: -l 127.0.0.1.
How This Interacts with Full-Page Cache
Object cache and full-page cache are not alternatives — they operate at different layers. A full-page cache (WP Rocket, W3 Total Cache's disk-enhanced mode, or Nginx FastCGI cache) serves pre-built HTML and bypasses PHP entirely for cached requests. Object cache only helps when PHP runs.
The practical implication: logged-in users, WooCommerce cart pages, and any URL excluded from full-page cache still hit PHP on every request. Object cache is what keeps those requests fast. On the test site, the WooCommerce cart page is excluded from full-page cache by default. With Redis enabled, its TTFB dropped from 831 ms to 389 ms — a 53% reduction that full-page cache would never have touched.
Do This First
Before installing either cache backend, run this sequence:
-
Measure your current TTFB with
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\n" https://yoursite.com/shop/— repeat 10 times and take the median. If it is under 300 ms, object cache may not be your bottleneck. -
Check autoloaded options size. Run this query against your database:
SELECT SUM(LENGTH(option_value)) / 1024 / 1024 AS autoload_mb
FROM wp_options
WHERE autoload = 'yes';
If autoload_mb exceeds 3 MB, object cache will help but you also have a plugin hygiene problem. Deactivate and delete plugins that are storing large serialized objects in wp_options autoload.
-
Install Redis Object Cache (the Till Krüss plugin), enable the drop-in, and re-run your TTFB measurement. The before/after comparison tells you exactly what you gained.
-
Set
maxmemoryandmaxmemory-policybefore you go to production. Skipping this step is the most common cause of Redis-related WordPress outages — the cache fills, Redis stops accepting writes, and the site either errors or falls back to uncached database reads silently.
Conclusion
The WordPress object cache decision comes down to two questions: what database query patterns does your site generate, and what does your host support?
For WooCommerce sites or any WordPress install with complex option group reads, Redis's native hash support produces measurably better cache hit rates and lower TTFB — 44% lower in this test versus the uncached baseline, versus 38% for Memcached. The difference is real but not catastrophic; Memcached is not a wrong choice if Redis is unavailable.
What is a wrong choice is running no persistent object cache on a WordPress site with more than a few dozen database queries per page load. The 742 ms baseline on a well-provisioned VPS dropped to 419 ms with four configuration changes. That 323 ms improvement is the kind of gain that moves Core Web Vitals scores and reduces server load simultaneously — no new hardware required.