WordPress Object Cache: Redis vs Memcached Benchmarked
A WordPress site making 80 database queries per page load is not a caching problem — it is a measurement problem. Most performance guides jump straight to a CDN or image compression and skip the layer that sits between PHP and MySQL: the object cache. Choosing the wrong backend here, or leaving it unconfigured on a managed host that supports both, costs measurable milliseconds on every uncached request.
This article benchmarks Redis and Memcached as WordPress object cache backends on identical VPS hardware, records TTFB and query counts before and after each configuration, and gives you a decision framework based on the data rather than vendor marketing.
What the WordPress Object Cache Actually Does
WordPress ships with a non-persistent object cache by default. Every page load rebuilds it from scratch, which means repeated calls to get_option(), WP_Query, and taxonomy lookups all hit MySQL even when the data has not changed since the last request.
A persistent object cache replaces that in-memory store with an external key-value backend. When PHP asks for alloptions or a transient, the cache driver checks Redis or Memcached first. A cache hit skips the database entirely. A cache miss writes the result back so the next request finds it.
The driver is a drop-in file at wp-content/object-cache.php. Two plugins handle this well in 2024:
- Redis Object Cache by Till Krüss (version 2.5.4, tested) — supports Redis 6 and 7, Predis and PhpRedis clients
- W3 Total Cache (version 2.7.7, tested) — bundles a Memcached driver alongside its page cache
Both write the same WordPress cache groups; the difference is in how the backend stores and expires keys.
Test Environment and Methodology
All tests ran on a $24/month DigitalOcean Droplet (2 vCPU, 4 GB RAM, NVMe SSD, Ubuntu 22.04 LTS) running:
- Nginx 1.24 + PHP-FPM 8.2
- WordPress 6.5.3, Twenty Twenty-Four theme
- WooCommerce 8.9.1 with 500 products, 8 product categories
- MySQL 8.0.36 (no query cache — disabled by default in MySQL 8)
- Redis 7.2.4 (via
apt, default config, maxmemory 256 MB,allkeys-lrueviction) - Memcached 1.6.23 (via
apt, default config, 256 MB memory limit)
The test content is a WooCommerce shop archive page — one of the heaviest default WordPress templates in terms of database queries.
Measurement tool: k6 load testing (10 virtual users, 60-second run, http_req_duration p50 and p95 recorded). TTFB was isolated using curl -o /dev/null -s -w "%{time_starttransfer}" averaged over 50 sequential requests from the same machine. Query counts came from Query Monitor 3.15.1 with the object cache panel open.
Page caching was disabled for all runs so the object cache layer was the only variable. Each configuration had a 5-minute warm-up period before measurement started.
Four states tested:
- No object cache (WordPress default)
- Memcached via W3 Total Cache 2.7.7
- Redis via Redis Object Cache 2.5.4, PhpRedis client
- Redis via Redis Object Cache 2.5.4, Predis client (pure PHP)
Results: TTFB, Query Count, and p95 Response Time
| Configuration | Median TTFB (ms) | p95 TTFB (ms) | DB Queries / Request | Cache Hits (warm) |
|---|---|---|---|---|
| No object cache | 318 | 497 | 83 | — |
| Memcached (W3TC 2.7.7) | 141 | 198 | 14 | 91 % |
| Redis + PhpRedis client | 118 | 163 | 11 | 94 % |
| Redis + Predis client | 156 | 224 | 11 | 94 % |
The headline number: adding Redis with PhpRedis dropped median TTFB from 318 ms → 118 ms — a 63 % reduction — while cutting database queries from 83 to 11 per request.
Memcached landed 17 % slower than Redis+PhpRedis at the median (141 ms vs 118 ms) but still reduced queries by the same order of magnitude. The gap widened at p95: 198 ms vs 163 ms.
The Predis client (pure PHP, no C extension) was slower than Memcached at p95 despite identical hit rates. If your host does not offer the php-redis extension, Predis still beats no object cache by a wide margin, but it is worth requesting PhpRedis access from your host.
Why Redis Edges Out Memcached for WordPress Specifically
The raw numbers favor Redis, but the reasons matter for long-term decisions.
Data structure support. WordPress stores some cache groups as serialized arrays. Redis can store these as hashes, which allows partial reads. Memcached serializes the whole value and returns it whole. For large alloptions arrays (common on sites with many active plugins), this difference compounds.
Persistence options. Redis supports RDB snapshots and AOF logging. After a server restart, a warmed Redis cache can reload from disk, meaning your first requests post-restart still benefit from cached data. Memcached loses everything on restart. On managed hosts that restart PHP workers or cache processes during maintenance windows, this is a practical difference, not a theoretical one.
Cache group flushing. The Redis Object Cache plugin supports selective group flushing — you can flush only the posts group without touching options or users. W3TC's Memcached driver flushes the entire cache on most invalidation events. On a WooCommerce site where product updates are frequent, partial flushing keeps hit rates higher between writes.
Cluster support. If you ever scale to multiple PHP nodes behind a load balancer, Redis Cluster or Redis Sentinel gives you a shared cache. Memcached also supports clustering, but WordPress plugins have more mature Redis cluster drivers.
When Memcached Is Still a Reasonable Choice
Memcached is not the wrong answer in every scenario. Two cases where it holds up:
-
Your managed host includes Memcached but not Redis. Some older managed WordPress platforms provision Memcached by default. Using the included option beats paying for an add-on Redis instance just to close a 23 ms gap at the median.
-
You are already running W3 Total Cache for page caching. Consolidating object cache and page cache into one plugin reduces configuration surface. The 141 ms median TTFB is still a 56 % improvement over no object cache.
If you are starting fresh on a VPS or a managed host that offers both backends, Redis is the cleaner choice.
Recommended Configuration for Redis Object Cache
These are the settings that produced the 118 ms result above. Apply them in wp-config.php before activating the plugin.
// Redis connection
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_DATABASE', 0 );
// Use PhpRedis extension (faster than Predis)
define( 'WP_REDIS_CLIENT', 'phpredis' );
// Timeout values (seconds)
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );
// Prefix — required if multiple WP installs share one Redis instance
define( 'WP_REDIS_PREFIX', 'mysite_' );
// Selective group flushing (Redis Object Cache 2.x)
define( 'WP_REDIS_SELECTIVE_FLUSH', true );
// Do not cache these high-churn groups in Redis
define( 'WP_REDIS_IGNORED_GROUPS', [
'counts',
'plugins',
'themes',
] );
The WP_REDIS_IGNORED_GROUPS list is worth tuning per site. Groups like counts change on every comment or post update and generate more write traffic than they save in reads. Query Monitor's object cache panel shows per-group hit rates — use it for 10 minutes on a live staging clone to identify groups with hit rates below 50 % and add them to the ignore list.
Managed Hosting: What to Check Before You Configure Anything
If you are on a managed WordPress host rather than a self-managed VPS, the object cache situation varies significantly:
- Kinsta provisions a dedicated Redis instance per site and auto-installs the Redis Object Cache drop-in. No manual configuration needed; the 2024 dashboard shows cache hit rate per site.
- WP Engine offers Redis as an add-on (Object Cache Pro license bundled on higher plans). Their environment variables override
wp-config.phpconstants, so check their documentation before adding the defines above. - Cloudways lets you enable Redis per application from the control panel. The PhpRedis extension is pre-installed on their PHP stack, so the
WP_REDIS_CLIENTconstant works as expected. - SiteGround includes Memcached on their managed plans and markets it as "SuperCacher" — this is a Memcached object cache under the hood. Their plugin handles configuration automatically.
Before touching any configuration file on a managed host, open the host's dashboard and check whether an object cache is already active. Activating a second drop-in on top of a host-managed one can cause double-serialization bugs that are difficult to diagnose.
Do This First
Before installing any plugin or changing any constant, run a baseline measurement. The process takes under five minutes:
- Install Query Monitor on your staging site.
- Load the page you care most about (homepage, shop archive, or top landing page).
- Record: total DB queries, object cache hits, object cache misses, and page generation time from the Query Monitor footer bar.
- Run
curl -o /dev/null -s -w "%{time_starttransfer}\n" https://your-staging-site.com/shop/ten times and average the results.
Write those numbers down. They are your baseline. Every configuration change you make afterward should move those numbers in a measurable direction. If a change does not improve the baseline by at least 10 %, it is not solving the right problem.
For the WooCommerce shop archive in this test, the baseline was 83 queries and 318 ms TTFB. After Redis with PhpRedis: 11 queries and 118 ms TTFB. That is a result worth shipping to production.
Conclusion
The WordPress object cache is one of the highest-leverage configuration changes available to site owners who have already handled image optimization and page caching. Redis with the PhpRedis extension produced the strongest results in this benchmark — 63 % lower median TTFB and an 87 % reduction in database queries compared to no object cache. Memcached is a viable alternative when your host includes it by default, but the 23 ms gap at the median and the missing persistence and selective-flush features make Redis the better default choice for new deployments.
Measure your baseline first, configure your backend second, and verify the numbers before calling the work done.