From connection refused to session lock timeout
When Redis causes trouble in a Magento environment, only a handful of error patterns are really common: refused connections, OOM errors on writes, and session lock timeouts during checkout. This article walks through each of these error patterns systematically, showing the diagnostic steps and the concrete fix.
Table of Contents
- 1. Systematic error diagnosis instead of guessing
- 2. Connection refused: the connection fails
- 3. OOM command not allowed: out of memory
- 4. Session lock timeouts during checkout
- 5. Read timeout and slow Redis responses
- 6. Max number of clients reached
- 7. Data loss after restart: persistence errors
- 8. Reading Magento logs correctly and mapping Redis errors
- 9. Error patterns compared
- 10. Summary
- 11. FAQ
1. Systematic error diagnosis instead of guessing
When a Magento store suddenly throws errors and Redis appears in the stack trace, the first impulse is often to restart the Redis service. In many cases this fixes the symptom in the short term, but rarely the cause, and the problem returns hours or days later. Systematic troubleshooting instead starts with three questions: what exactly does Magento report in the exception log, what does Redis itself report in its own log, and what does redis-cli INFO show at the time of the error.
Most Redis problems in Magento environments can be traced back to a small number of recurring error patterns: connection errors from misconfiguration or network problems, memory errors from missing or misconfigured eviction policy, and locking problems in session handling under parallel requests. Whoever knows these patterns can usually narrow down the cause within a few minutes instead of searching in the dark for hours.
One important principle upfront: Redis errors in Magento almost always appear as generic PHP exceptions like RedisException or CredisException, whose message text usually contains the actual Redis error message verbatim. The first thing to check should therefore always be the full exception message, not just the exception type, because that is where the decisive clues live.
2. Connection refused: the connection fails
The error message Connection refused or php_network_getaddresses failed means Magento cannot reach the configured Redis host and port at all. The most common causes are a wrong hostname or port in env.php, a Redis process that is not running or has crashed, a firewall rule blocking the port, or a bind directive in redis.conf that only listens on 127.0.0.1 while Magento connects from a different host.
Systematic diagnosis starts with a simple TCP connectivity test independent of Magento, for example redis-cli -h HOST -p PORT ping. If Redis does not respond with PONG here, the problem clearly sits at the infrastructure level, not in the Magento configuration. A second common case is a Redis process that runs but crashes repeatedly due to an OS OOM kill, because it consumes more memory than the server physically has. In that case, dmesg | grep -i redis or journalctl -u redis shows the corresponding kill events.
# Step 1: raw TCP connectivity test, independent of Magento
redis-cli -h 10.0.1.10 -p 6379 ping
# expected: PONG
# Step 2: check if Redis is bound to the right interface
grep -E "^bind|^port" /etc/redis/redis.conf
# Step 3: check the systemd service status and recent crashes
systemctl status redis-server
journalctl -u redis-server --since "1 hour ago" | grep -i "oom\|killed\|error"
# Step 4: verify what Magento actually has configured
grep -A 15 "'cache' =>" app/etc/env.php | grep -E "server|port"
# Step 5: check firewall rules for the Redis port
sudo iptables -L -n | grep 6379
In Docker or Kubernetes setups, another common mistake is using localhost or 127.0.0.1 in env.php even though Redis runs in its own container. Here the service name from the Docker network or Kubernetes service must be used, not the local loopback address. Otherwise the result is exactly the same Connection refused message even though Redis itself is running fine.
3. OOM command not allowed: out of memory
The message OOM command not allowed when used memory greater than maxmemory is unambiguous: Redis has reached its configured memory limit and the maxmemory-policy is set to noeviction, which means Redis does not automatically remove existing keys to make room. New write operations are then consistently rejected until memory is freed manually or the limit is raised.
This error occurs particularly often on the session instance in Magento environments, because noeviction is deliberately set there to prevent active user sessions from being deleted under memory pressure. If the number of concurrent sessions rises above the planned capacity, for example during a marketing campaign, memory fills up faster than expected, and new logins or cart updates fail.
# Diagnose: check current memory usage vs the configured limit
redis-cli -p 6380 info memory | grep -E "used_memory_human:|maxmemory_human:|maxmemory_policy:"
# Find the biggest memory consumers among key patterns
redis-cli -p 6380 --bigkeys
# Short-term fix: raise the limit if the server has free RAM
redis-cli -p 6380 config set maxmemory 4gb
# Better fix for object/page cache (never for sessions):
# switch policy to evict least recently used keys automatically
redis-cli -p 6381 config set maxmemory-policy allkeys-lru
# Persist the change so it survives a restart
echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis-fpc.conf
For the object cache and the full page cache, allkeys-lru or allkeys-lfu is almost always the right choice, because lost cache entries only trigger a fresh database lookup and cause no data loss. For the session instance, noeviction is deliberately correct, instead the maxmemory limit needs to be sized realistically for expected peak load, combined with a sensible session TTL that reliably expires old sessions.
4. Session lock timeouts during checkout
A particularly tricky error pattern is the session lock timeout, which usually shows up as a hanging or very slow checkout without a clear error message appearing in the frontend. Magento uses a locking mechanism for Redis backed sessions to prevent two parallel requests from the same user writing to the same session simultaneously and overwriting each other's data. If a request holds the session longer than necessary, for example due to a slow external API call during payment processing, all subsequent requests from the same user have to wait until the lock is released.
The problem intensifies when a frontend fires multiple AJAX requests simultaneously, for example for cart updates, shipping cost calculation and cross-selling suggestions in parallel. Every one of these requests tries to acquire the same session lock and waits, instead of running in parallel. In total this leads to a cascading delay that feels to the user like a hanging checkout, even though Redis itself is technically working correctly.
// app/etc/env.php: tune session locking behaviour for Redis-backed sessions
'session' => [
'save' => 'redis',
'redis' => [
'host' => '10.0.1.30',
'port' => '6380',
'password' => '',
'timeout' => '2.5',
// Lower bot: fail fast instead of blocking indefinitely on a stuck lock
'bot_first_lifetime' => '60',
'bot_lifetime' => '7200',
'max_lifetime' => '2592000',
'min_lifetime' => '60',
// Break locks that are held too long by a stalled request
'disable_locking' => '0',
'min_sleep' => '2000',
'max_sleep' => '1000000',
'break_after_frontend' => '5',
'break_after_adminhtml' => '30',
'log_level' => '1',
],
],
The parameters break_after_frontend and break_after_adminhtml define after how many seconds a stuck lock is forcibly broken, instead of blocking a waiting request indefinitely. A value too low risks race conditions on genuinely long operations, a value too high leaves users waiting minutes on a single stuck request. In practice a value between three and eight seconds has proven effective for the frontend, while the adminhtml area with longer import operations can be sized more generously.
5. Read timeout and slow Redis responses
A Read timeout indicates that Redis is reachable but does not respond within the configured time window. The most common cause in production environments is a blocking command running against a large dataset, first and foremost KEYS *, which on a production instance with millions of keys completely blocks the single processing thread for several seconds. During that time, no other requests can be served, which leads to a cascade of timeouts.
Instead of KEYS, production environments should exclusively use SCAN, which walks the keyspace incrementally in small batches without blocking the server. A second common trigger for timeouts is network latency between the application server and the Redis instance, especially in cloud setups spanning multiple availability zones. When Magento and Redis run in different zones, even a normal network latency of a few milliseconds per request can add up to noticeable load times across thousands of cache accesses per page.
6. Max number of clients reached
The error message ERR max number of clients reached shows that the number of concurrent connections has reached the configured maxclients limit, 10000 by default in modern Redis versions. In practice this error usually occurs much earlier, because the operating system limit for open file descriptors is lower than the configured Redis limit. A typical scenario: PHP-FPM opens a new Redis connection on every request instead of reusing connections, and during a traffic spike thousands of open but unused connections accumulate.
Persistent connections via the persistent parameter in env.php significantly reduce this risk, because PHP-FPM workers reuse the same Redis connection across multiple requests instead of establishing and tearing down a new TCP connection on every request. In addition, the timeout for idle connections in redis.conf should be set, so orphaned connections get closed automatically instead of staying open permanently.
7. Data loss after restart: persistence errors
When all sessions are lost after a Redis restart and users suddenly get logged out, this is usually a persistence problem. For the object cache and full page cache this is harmless, since that data is temporary anyway. For the session instance, however, data loss after a restart is a real problem that can be avoided with correctly configured persistence.
Redis offers two persistence mechanisms: RDB snapshots, which write the complete dataset to disk at configurable intervals, and AOF, which continuously appends every write command to a log file and restores it on restart. For sessions, AOF with appendfsync everysec is the right choice, because it loses at most one second of data in a failure, whereas RDB snapshots can mean significantly more data loss depending on the interval.
; /etc/redis/redis-session.conf: durable persistence for session data
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
; Disable RDB snapshots for the session instance entirely,
; AOF alone is sufficient and avoids fork() pauses under load
save ""
; Verify AOF integrity after an unclean shutdown
; redis-check-aof --fix appendonly.aof
8. Reading Magento logs correctly and mapping Redis errors
Magento logs Redis errors by default in var/log/exception.log and var/log/system.log, though often with generic class names like Cm_Cache_Backend_Redis or Magento\Framework\Cache\Backend\RemoteSynchronizedCache, which say little at first glance. The decisive part usually sits at the end of the exception message, where the actual Redis response is passed through, for example -ERR max number of clients reached or READONLY You can't write against a read only replica.
Beyond the Magento log, it is always worth checking Redis's own log, by default under /var/log/redis/redis-server.log, as well as SLOWLOG GET 10, which lists the ten slowest recently executed commands. This combination of Magento exception, Redis log and slowlog delivers a complete picture in most cases, without requiring guesswork.
# Combine Magento exception log with Redis-side diagnostics
tail -n 50 var/log/exception.log | grep -i "redis\|credis"
# Ten slowest Redis commands recently executed
redis-cli -p 6379 slowlog get 10
# Currently connected clients and how they are consuming connections
redis-cli -p 6379 client list | awk '{print $2, $5}' | sort | uniq -c | sort -rn
# Tail the Redis server log for errors around the incident time
tail -n 100 /var/log/redis/redis-server.log | grep -i "error\|warning\|oom"
9. Error patterns compared
The following table summarizes the most common Redis error patterns in Magento environments, along with the most likely cause and the first diagnostic step for each.
| Error Pattern | Most Likely Cause | First Diagnostic Step |
|---|---|---|
| Connection refused | Wrong host/port, Redis down, firewall | redis-cli -h HOST -p PORT ping |
| OOM command not allowed | maxmemory reached, noeviction set | Check INFO memory |
| Session lock timeout | Parallel AJAX, slow API call | Check break_after_frontend |
| Read timeout | KEYS command, network latency | SLOWLOG GET 10 |
| Max clients reached | No persistent connections | Check CLIENT LIST |
These five error patterns cover the majority of all Redis related incidents in Magento environments in practice. A structured runbook documenting exactly these diagnostic steps significantly reduces average time-to-resolution, because the operations team does not need to research from scratch on every incident.
10. Summary
The most common Redis errors in Magento environments are well known and follow clear patterns: connection refused points to network or configuration problems, OOM command not allowed to a reached memory limit with the wrong eviction policy, and session lock timeouts to parallel requests waiting too long on the same lock. Read timeouts usually arise from blocking commands like KEYS or from network latency, while reached client limits almost always come down to missing connection pooling configuration.
Systematic diagnosis with redis-cli, INFO, SLOWLOG and the Magento log files leads to the cause within a few minutes in most cases. A runbook with the described diagnostic steps per error pattern makes troubleshooting understandable for every team member, regardless of who sees the alert first.
Redis Troubleshooting for Magento: The Key Points at a Glance
Connection refused
redis-cli ping as the first test, then check env.php configuration and firewall rules.
OOM command not allowed
Set maxmemory-policy to allkeys-lru for cache instances, size the limit realistically for sessions.
Session lock timeout
Tune break_after_frontend and break_after_adminhtml to real request duration.
Diagnostic tools
Always check INFO, SLOWLOG GET, CLIENT LIST and Redis's own log alongside the Magento log.