The Error
Your app tries to connect to Redis and gets this back:
(error) ERR max number of clients reached
Redis hit its configured client limit and is turning away new connections. Nothing gets in until something else disconnects.
Four things typically cause this:
- A connection leak โ your app opens connections but never closes them
- Multiple app instances each maintaining their own connections instead of sharing a pool
- The default
maxclientslimit (10,000) is genuinely too low for your traffic - A traffic spike opened thousands of short-lived connections that haven't cleaned up yet
Step 1: Check the Current Client Count
First, confirm the problem and see what you're dealing with:
redis-cli INFO clients
Sample output:
# Clients
connected_clients:10001
cluster_connections:0
maxclients:10000
client_recent_max_input_buffer:20480
client_recent_max_output_buffer:0
blocked_clients:0
tracking_clients:0
clients_in_timeout_table:0
connected_clients at 10,001 against a maxclients of 10,000 โ that's your confirmation.
Now see what those clients are actually doing:
redis-cli CLIENT LIST
Each line shows the client's IP, last command, and idle time in seconds. Connections sitting idle for 300+ seconds with no recent commands are almost certainly leaks.
Step 2: Kill Idle Connections (Quick Fix)
Need to free up slots right now without restarting Redis? Kill the idle ones.
On Redis 7.4+, one command does it:
# Kill all clients idle for more than 5 minutes
redis-cli CLIENT KILL MAXAGE 300
On older versions, parse CLIENT LIST manually:
redis-cli CLIENT LIST | awk -F'[= ]' '{
for(i=1;i= 300) print id
}
}' | xargs -I {} redis-cli CLIENT KILL ID {}
Or target a single connection by its ID from the CLIENT LIST output:
redis-cli CLIENT KILL ID 12345
This buys you breathing room. It won't stop the problem from coming back.
Step 3: Increase maxclients (If the Limit Is Too Low)
Sometimes the limit just isn't high enough for your actual workload. Here's how to raise it.
Option A โ Change at runtime (no restart needed)
redis-cli CONFIG SET maxclients 20000
Option B โ Change in redis.conf (survives restarts)
Open your Redis config โ usually at /etc/redis/redis.conf or /etc/redis.conf:
sudo nano /etc/redis/redis.conf
Find and update:
maxclients 20000
Then reload:
redis-cli CONFIG REWRITE
sudo systemctl reload redis
Option C โ Docker / docker-compose
services:
redis:
image: redis:7
command: redis-server --maxclients 20000
OS file descriptor limit: Redis caps maxclients at the OS file descriptor limit minus 32 (reserved for internal use). If you set 20,000 but ulimit -n returns 1024, Redis will silently apply a much lower value. Fix it in /etc/security/limits.conf:
redis soft nofile 65535
redis hard nofile 65535
Step 4: Fix Connection Leaks in Your App
Raising the limit is a band-aid. If connections are leaking, you'll hit the ceiling again โ just later. Track down where your app isn't releasing connections and fix it there.
Node.js (ioredis)
The most common mistake: creating a new Redis client per request. Each call opens a new connection that never closes.
// BAD โ a fresh connection on every request, none ever closed
app.get('/data', async (req, res) => {
const client = new Redis();
const val = await client.get('key');
res.json(val);
});
// GOOD โ one client created once, shared by all requests
const redis = new Redis({ host: 'localhost', port: 6379 });
app.get('/data', async (req, res) => {
const val = await redis.get('key');
res.json(val);
});
Python (redis-py)
Use ConnectionPool with an explicit cap so the pool can't grow unbounded:
import redis
pool = redis.ConnectionPool(
host='localhost',
port=6379,
max_connections=50
)
client = redis.Redis(connection_pool=pool)
PHP (Predis / PhpRedis)
PHP-FPM gives every worker its own persistent connection. Do the math before raising maxclients: pm.max_children ร number_of_servers. For example, 50 workers across 4 app servers means 200 connections minimum โ set maxclients above that with headroom to spare.
Step 5: Set a Connection Timeout
Make Redis clean up abandoned connections automatically. Add these two lines to redis.conf:
# Drop clients that go silent for 5 minutes
timeout 300
# Send TCP keepalive probes every 60 seconds
tcp-keepalive 60
Apply without restarting:
redis-cli CONFIG SET timeout 300
redis-cli CONFIG SET tcp-keepalive 60
Verify the Fix
Watch the client count live while your app runs under normal load:
watch -n 2 'redis-cli INFO clients | grep connected_clients'
connected_clients should stay comfortably below maxclients. If it was creeping up before, you'll see it stabilize now.
Confirm the new limit took effect:
redis-cli CONFIG GET maxclients
Quick Reference
- Immediate relief: Kill idle connections with
CLIENT KILL MAXAGE 300(Redis 7.4+) orCLIENT KILL ID - Short-term fix: Raise
maxclientswithCONFIG SET - Permanent fix: Set
maxclientsinredis.conf, fix connection leaks in app code, raise OS file descriptor limits - Prevention: Use a connection pool, set
timeoutin Redis config, monitorconnected_clientscontinuously โ Prometheus + redis_exporter is the standard setup for this

