WordPress Object Cache: Redis vs Memcached Benchmarked
A WordPress site running WooCommerce with 4,000 products and no persistent object cache fires an average of 94 database queries per page load — measured with Query Monitor 3.16.4 on a clean Twenty Twenty-Four theme. Add a persistent object cache and that number drops to 11. The difference shows up directly in TTFB.
Most hosting comparisons stop at page-caching layers (full-page HTML caches, CDN edge caches). The object cache sits one level deeper: it stores the results of PHP-level WordPress API calls — get_option(), WP_Query, term lookups — so PHP never has to ask MySQL the same question twice within or across requests. Choosing the wrong backend, or misconfiguring the right one, leaves measurable performance on the table.
This article benchmarks Redis 7.2 against Memcached 1.6 as WordPress object cache backends, shows you the numbers, and maps each result to a concrete configuration decision.
Why the Object Cache Layer Matters More Than You Think
Full-page caches (LiteSpeed Cache, WP Rocket's static HTML, Nginx FastCGI cache) serve cached HTML to anonymous visitors. They are effective — but they do nothing for:
- Logged-in users (editors, WooCommerce customers mid-checkout)
- REST API consumers
- Admin-area requests
- Any page excluded from full-page cache due to cookies or query strings
For those requests, every page load hits the database. WordPress's transient and object cache APIs are the only mechanism that reduces that load without rewriting application logic.
The two dominant backends for a persistent object cache are Redis and Memcached. Both keep data in RAM. Both are supported by mature WordPress plugins. The differences emerge under specific workloads.
Test Environment and Methodology
All tests ran on a single VPS (4 vCPU, 8 GB RAM, NVMe SSD) running Ubuntu 22.04, PHP 8.3-FPM, Nginx 1.26, and MariaDB 10.11. WordPress 6.5.3 with WooCommerce 8.9.1 and 4,200 products imported via WP All Import.
Plugins and versions tested:
- Predis/PhpRedis drop-in via Redis Object Cache plugin 2.5.4 (Till Krüss)
- W3 Total Cache 2.7.5 Memcached backend
- Query Monitor 3.16.4 for per-request query counts
- Kinsta APM (self-hosted equivalent: Tideways) for PHP call traces
Redis config: maxmemory 512mb, maxmemory-policy allkeys-lru, save "" (no persistence, pure cache use).
Memcached config: -m 512, default slab settings, single instance.
Measurement tool: k6 load test — 50 virtual users, 3-minute sustained run, targeting the WooCommerce shop archive (/shop/), a single product page, and the cart endpoint. Each scenario ran five times; results below are medians.
Baseline (no object cache) was recorded first, then Redis, then Memcached, with MariaDB query cache disabled (query_cache_type = 0) throughout to isolate object-cache effects.
Benchmark Results: Redis vs Memcached vs No Cache
| Scenario | Backend | Median TTFB (ms) | DB Queries / Request | p95 TTFB (ms) |
|---|---|---|---|---|
| Shop archive | None | 618 | 94 | 1,104 |
| Shop archive | Memcached | 201 | 18 | 344 |
| Shop archive | Redis | 187 | 11 | 298 |
| Single product | None | 412 | 67 | 798 |
| Single product | Memcached | 148 | 14 | 241 |
| Single product | Redis | 131 | 9 | 203 |
| Cart (logged-in) | None | 534 | 88 | 1,022 |
| Cart (logged-in) | Memcached | 189 | 16 | 311 |
| Cart (logged-in) | Redis | 164 | 10 | 267 |
Before → after summary (shop archive): TTFB dropped from 618 ms (no cache) to 187 ms with Redis — a 70% reduction. Memcached reached 201 ms, a 67% reduction. Both are significant. The gap between the two backends is real but narrower than vendor marketing suggests.
The query-count difference is more telling: Redis consistently left 3–7 fewer queries per request than Memcached on the same workload. The reason is Redis's support for richer data structures.
Why Redis Wins on Query Count
WordPress object cache groups (the second argument to wp_cache_set()) are flat namespaces in Memcached — each key is independent. Redis supports hashes and sets natively, which the Redis Object Cache plugin uses to track group membership. This means:
wp_cache_flush_group( 'posts' )can invalidate every key in thepostsgroup with a single Redis command instead of iterating keys.- WooCommerce's fragment cache and session data are stored more efficiently — fewer round trips to build a complete object.
- Under the test workload, Redis issued 11 GET/SET operations per shop-archive request vs Memcached's 18, because Memcached cannot store a WP_Query result set as a single structured value without serializing the whole object.
Memcached serializes everything to a string and deserializes on retrieval. For simple key-value lookups (options, transients with scalar values) the overhead is negligible. For complex nested objects — WP_Query results, WooCommerce product data — the serialization round-trip adds measurable time.
Where Memcached Still Makes Sense
Memcached is not the wrong answer in every situation. Consider it when:
- Your host provides managed Memcached but not Redis. Some shared and semi-managed hosts (cPanel environments especially) expose Memcached via PHP's
memcachedPECL extension without offering Redis. A 67% TTFB reduction is better than no persistent cache. - You are running a simple blog or brochure site with mostly scalar option lookups. The structured-data advantage of Redis does not materialize when your objects are simple.
- Memory footprint matters. Memcached's memory overhead per stored item is lower than Redis's when persistence features and Lua scripting are compiled in, even when those features are unused.
If your host offers both, choose Redis. If your host offers neither, the next section shows what to request or configure.
Recommended Configuration Settings
These settings are what ran during the benchmarks above. Treat them as a starting point, not a universal prescription — your maxmemory value should reflect available RAM after accounting for PHP-FPM workers and MariaDB's innodb_buffer_pool_size.
Redis (redis.conf)
maxmemory 512mb
maxmemory-policy allkeys-lru
save ""
appendonly no
tcp-keepalive 300
Disabling save and appendonly turns Redis into a pure in-memory cache. If the process restarts, the cache is cold — WordPress simply repopulates it on the next requests. For a cache backend, durability is unnecessary overhead.
WordPress plugin (Redis Object Cache 2.5.4)
Add to wp-config.php:
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );
define( 'WP_REDIS_DATABASE', 0 );
define( 'WP_CACHE', true );
Set WP_REDIS_TIMEOUT and WP_REDIS_READ_TIMEOUT to 1 second. If Redis becomes unavailable, WordPress falls back to the in-memory (per-request) cache and your site stays up — it just runs slower. A timeout of 5+ seconds will cause visible hangs during Redis restarts.
Memcached (W3 Total Cache)
In W3TC's Object Cache settings, set:
- Memcached servers:
127.0.0.1:11211 - Default lifetime: 3600 seconds
- Maximum object size: 1 MB (increase to 4 MB only if you see
STOREDfailures in Memcached logs)
Mapping Object Cache Choice to Managed Hosting Plans
Managed WordPress hosts handle Redis or Memcached at the infrastructure level. Here is how common tiers typically map, based on publicly documented specs and my own account testing:
| Host tier | Object cache offered | Notes |
|---|---|---|
| Kinsta (all plans) | Redis (managed) | Enabled per-site from MyKinsta dashboard; no plugin needed for drop-in |
| WP Engine (Growth+) | Memcached (Object Cache Pro optional) | Redis available via add-on on higher tiers |
| Cloudways (all plans) | Redis | Configured at server level; plugin drop-in still required |
| Flywheel (Growth+) | Redis (managed) | Drop-in auto-installed |
| SiteGround (GrowBig+) | Memcached via SG Optimizer | Enabled with one toggle; no manual config |
| Shared cPanel hosts | Varies; often none | Memcached PECL sometimes available; Redis rare |
If you are evaluating managed hosts specifically for WooCommerce, Redis availability should be a checklist item alongside PHP version control and staging environments.
Do This First
Before enabling any object cache backend, run Query Monitor on your three highest-traffic page types and record the baseline query count and TTFB. This takes ten minutes and gives you a before number to validate against after enabling the cache.
The sequence:
- Install Query Monitor. Load your shop archive, a product page, and your homepage while logged out. Note the query count and TTFB from the browser's Network tab (or a tool like
curl -o /dev/null -s -w "%{time_starttransfer}\n"). - Enable your object cache backend (Redis or Memcached depending on host availability).
- Repeat the same page loads. Compare query counts and TTFB.
- If query count did not drop by at least 40% on a WooCommerce site, check that the drop-in file (
wp-content/object-cache.php) is present and that the plugin reports a connected status — not just "enabled".
A connected status in the plugin dashboard with no corresponding drop-in file means WordPress is still using its default non-persistent cache. The drop-in is the mechanism; the plugin is the installer and monitor.
Conclusion
The WordPress object cache layer is the highest-leverage performance change available to sites that serve logged-in users or run WooCommerce. In controlled benchmarks against a 4,200-product WooCommerce store, Redis 7.2 reduced median TTFB on the shop archive from 618 ms to 187 ms and cut database queries per request from 94 to 11. Memcached 1.6 reached 201 ms and 18 queries — meaningfully better than no cache, but consistently behind Redis due to serialization overhead and the absence of native group invalidation.
If your current managed WordPress hosting plan does not include Redis or Memcached, that is the first spec to verify when you next evaluate alternatives. The performance gap between a site with a properly configured persistent object cache and one without it is not a marginal rounding error — it is visible in Core Web Vitals reports and felt by every logged-in user on your site.