Using Redis as a cache for WordPress (via the Redis Object Cache plugin) is a great way to cut database load and speed up page generation. Two things determine how well it works: where Redis runs (same host, Docker, or a managed service like Amazon ElastiCache for Redis) and the fact that Redis’s default configuration is not tuned for WordPress caching.
Out of the box, Redis ships with disk persistence enabled, no memory ceiling (maxmemory 0), and a noeviction policy—sensible for a datastore, but sub‑optimal for a high‑churn object cache. For WordPress you want an ephemeral, memory‑bounded cache with an allkeys-* eviction policy, active defragmentation, and lazy frees enabled.
Why the defaults aren’t ideal for WordPress
maxmemoryis unset → the OS may OOM‑kill Redis under pressure.maxmemory-policy noeviction→ writes can fail at high memory instead of evicting cold keys.- Persistence is enabled → unnecessary disk I/O and longer restarts for a cache‑only role.
- Active defragmentation is off → RSS can bloat long after traffic subsides.
This guide gives production‑ready settings for each deployment scenario, with copy‑pasteable snippets, and a short checklist to verify things are working.
TL;DR (Quick Recipe)
- Treat Redis as ephemeral cache (no disk durability).
- Set a memory ceiling and an eviction policy:
maxmemory+allkeys-lfu(orallkeys-lru). - Turn on active defragmentation and lazyfree to stabilize memory.
- Prefer phpredis client with persistent connections from PHP-FPM.
- Give objects a sane TTL (1–24h) and a unique key prefix per site.
- Monitor:
redis-cli --stat,INFO,SLOWLOG,latency doctor.
Baseline: Redis as a WordPress Cache (applies everywhere)
Use these baseline settings whether Redis is local, containerized, or managed:
Key Redis settings
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# Treat as cache only: disable on-disk persistence save "" appendonly no # Memory ceiling & eviction (tune size to your host/service) maxmemory 1gb # adjust to your environment maxmemory-policy allkeys-lfu # or allkeys-lru maxmemory-samples 7 # better sampling for LFU/LRU # Memory stability activedefrag yes active-defrag-cycle-min 10 active-defrag-cycle-max 75 # Free deletes/expirations off the main thread lazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes # Connection hygiene tcp-keepalive 60 timeout 0 # keep pooled connections alive # Observability latency-monitor-threshold 100 # collect latency samples (µs) loglevel notice |
Choose
maxmemory: On a dedicated Redis host, start with ~50–70% of RAM. On a shared web server, start smaller (e.g., 512MB–1GB) and watch evictions and OS memory pressure.
WordPress plugin (typical) wp-config.php additions
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Prefer the phpredis PHP extension define('WP_REDIS_CLIENT', 'phpredis'); // Connection (examples — pick the one that matches your setup below) // define('WP_REDIS_HOST', '127.0.0.1'); // define('WP_REDIS_PORT', 6379); // If using TLS (e.g., ElastiCache with in-transit encryption): // define('WP_REDIS_SCHEME', 'tls'); // Performance knobs define('WP_REDIS_MAXTTL', 86400); // 24h; adjust to your cache strategy define('WP_REDIS_PREFIX', 'wp_'); // or per-site slug (see below) define('WP_CACHE_KEY_SALT', 'example.com:'); // uniqueness across sites // Connection reuse (if supported by your plugin version) define('WP_REDIS_PERSISTENT', true); |
Prefixing: Use a unique
WP_CACHE_KEY_SALT(orWP_REDIS_PREFIX) per site (e.g., domain name) to avoid key collisions in shared Redis.
Scenario A — Redis on the Web Server (localhost)
Best for: single server or small clusters where latency should be minimal and ops are simple.
Advantages
- Lowest latency (UNIX socket possible)
- Easiest to operate
How to configure
- Install Redis from your distro or a trusted package (prefer 7.x).
- Drop the baseline
redis.confabove into/etc/redis/redis.conf. - (Optional) Use a UNIX socket for lower overhead:
1234unixsocket /var/run/redis/redis.sockunixsocketperm 770# Add your web/PHP-FPM user to the redis group - Set
maxmemoryto a safe ceiling for your host. - Restart Redis and point WordPress to the socket or
127.0.0.1:6379.
WordPress config example (UNIX socket)
|
1 2 3 4 |
// If your plugin supports sockets, you can use a path like this: // define('WP_REDIS_SOCKET', '/var/run/redis/redis.sock'); // Otherwise, stick with 127.0.0.1:6379. |
Verification
redis-cli -s /var/run/redis/redis.sock INFO memory(or-h 127.0.0.1)- Ensure
evicted_keysrises slowly onceused_memorynearsmaxmemory. - Watch
mem_fragmentation_ratioand runMEMORY PURGEduring a maintenance window if fragmentation climbs.
Scenario B — Redis in Docker
Best for: containerized stacks (Docker Compose, Swarm, or K8s) that isolate services.
Advantages
- Easy, reproducible deployments
- Clean separation between app and cache
docker-compose.yml (example)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
version: '3.9' services: redis: image: redis:7-alpine command: ["redis-server", "/usr/local/etc/redis/redis.conf"] volumes: - ./redis.conf:/usr/local/etc/redis/redis.conf:ro # No /data volume needed for cache-only ports: - "6379:6379" # expose only if needed outside the compose network healthcheck: test: ["CMD", "redis-cli", "PING"] interval: 10s timeout: 2s retries: 5 wordpress: image: wordpress:php8.2-fpm environment: # ... your DB env vars ... depends_on: - redis # Connect via service DNS name "redis" on port 6379 |
redis.conf
- Use the baseline from above.
- Set
maxmemoryappropriate to the container memory limit. If using Docker memory limits, ensure the container has enough headroom (Redis will not see host limits automatically).
WordPress config example
|
1 2 3 |
define('WP_REDIS_HOST', 'redis'); // service name from compose define('WP_REDIS_PORT', 6379); |
Kubernetes notes
- Use a
DeploymentorStatefulSetfor Redis with aConfigMapforredis.conf. - Add
resourcesrequests/limits and areadinessProbeusingredis-cli PING.
Scenario C — Amazon ElastiCache for Redis
Best for: high availability, managed patching, and easy scaling in AWS.
Topology
- Replication group with 1 primary + ≥1 replica; enable Multi‑AZ and automatic failover.
- Start with cluster mode disabled (single endpoint) unless you specifically need sharding, which requires cluster‑aware clients.
Parameters (Parameter Group)
- Disable persistence: set
saveto empty (""). - Eviction:
maxmemory-policy = allkeys-lfu(orallkeys-lru). - Memory stability:
activedefrag = yes; enablelazyfree-*options if available. - Connection hygiene:
tcp-keepalive = 60. - (ElastiCache sets
maxmemoryautomatically per node size; choose instance classes with enough headroom.)
Security
- Place Redis in a private subnet; restrict Security Groups to your app servers.
- If in‑transit encryption is enabled, connect over TLS.
WordPress config examples
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Plain (no TLS) define('WP_REDIS_HOST', 'my-redis.xxxxxx.ng.0001.use1.cache.amazonaws.com'); // TLS (if enabled) define('WP_REDIS_SCHEME', 'tls'); define('WP_REDIS_HOST', 'my-redis.xxxxxx.use1.cache.amazonaws.com'); // phpredis also supports "tls://host" style in WP_REDIS_HOST for some setups // Auth token (if configured) // define('WP_REDIS_PASSWORD', '...'); // Timeouts (network has more jitter than localhost) define('WP_REDIS_TIMEOUT', 1.0); define('WP_REDIS_READ_TIMEOUT', 1.0); |
Failover
- Point WordPress at the primary endpoint of the replication group. On failover, ElastiCache promotes a replica; the primary endpoint DNS updates automatically.
Verification
- From an EC2 instance in the same VPC:
1234redis-cli -h <primary-endpoint> -p 6379 --tls # add -a <token> if auth is onINFO memoryINFO stats - Watch
evicted_keys, hit/miss rates, and latency.
Monitoring & Tuning Checklist
- Hit ratio:
keyspace_hitsvskeyspace_misses→ adjust TTLs and cache coverage. - Evictions:
evicted_keys→ steady non‑zero is normal at capacity; spikes suggest undersizedmaxmemoryor too‑short TTLs. - Fragmentation:
mem_fragmentation_ratio→ >2 for long periods? Enableactivedefragand occasionally runMEMORY PURGEduring low traffic. - Latency:
latency doctor,SLOWLOG GET 128→ track slow commands and outliers. - Connections: Prefer persistent connections; avoid connection churn.
- Backpressure: For Docker/K8s, ensure container/node memory limits exceed Redis
maxmemoryby 20–30% for overhead.
Troubleshooting
- High misses, low evictions: Your cache may be under‑utilized—confirm the plugin is enabled, keys are being set, and TTLs aren’t too short.
- Frequent evictions: Increase
maxmemory(if you can), useallkeys-lfu, and consider lengthening TTLs for truly hot objects. - Memory keeps growing after traffic drops: Check fragmentation; run
MEMORY PURGEor restart in a window. - Connection errors in ElastiCache: Verify Security Groups, subnet routing, and TLS/auth settings; increase timeouts slightly.
- Shared Redis for multiple sites: Use unique
WP_CACHE_KEY_SALT/prefix per site.
Appendix A — Baseline redis.conf (cache‑only)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
save "" appendonly no # Adjust to your host/service maxmemory 1gb maxmemory-policy allkeys-lfu maxmemory-samples 7 activedefrag yes active-defrag-cycle-min 10 active-defrag-cycle-max 75 lazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes tcp-keepalive 60 timeout 0 latency-monitor-threshold 100 loglevel notice |
Appendix B — Minimal docker-compose.yml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
version: '3.9' services: redis: image: redis:7-alpine command: ["redis-server", "/usr/local/etc/redis/redis.conf"] volumes: - ./redis.conf:/usr/local/etc/redis/redis.conf:ro healthcheck: test: ["CMD", "redis-cli", "PING"] interval: 10s timeout: 2s retries: 5 wordpress: image: wordpress:php8.2-fpm depends_on: - redis environment: # DB_*, WP_*, etc. |
Appendix C — Example wp-config.php snippet
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Redis Object Cache (common settings) define('WP_REDIS_CLIENT', 'phpredis'); // One of the following depending on your setup: // Localhost TCP // define('WP_REDIS_HOST', '127.0.0.1'); // define('WP_REDIS_PORT', 6379); // Docker service name // define('WP_REDIS_HOST', 'redis'); // define('WP_REDIS_PORT', 6379); // ElastiCache (TLS optional) // define('WP_REDIS_SCHEME', 'tls'); // define('WP_REDIS_HOST', 'my-redis.xxxxxx.use1.cache.amazonaws.com'); // define('WP_REDIS_PASSWORD', '...'); // if auth enabled // Cache hygiene define('WP_REDIS_MAXTTL', 86400); // typical 1 day define('WP_CACHE_KEY_SALT', 'example.com:'); // make unique per site // Optional, if supported by your plugin version define('WP_REDIS_PERSISTENT', true); |
Need a hand?
If you share your RAM/CPU budget, traffic profile, and whether you’re on localhost, Docker, or ElastiCache, we can recommend an initial maxmemory, TTL strategy, and eviction policy tailored to your site(s).




