What's Actually Happening
Redis client connection timeouts occur when clients cannot establish or maintain connections to Redis server. This happens due to network issues, server overload, firewall blocks, or client configuration problems.
The Error You'll See
Connection timeout:
```bash $ redis-cli -h redis-server ping
Could not connect to Redis at redis-server:6379: Connection timed out ```
Application error:
RedisConnectionException: Unable to connect to Redis server
Host: redis-server
Port: 6379
Timeout: 5000ms exceededJedis error:
JedisConnectionException: java.net.SocketTimeoutException: connect timed outredis-py error:
redis.exceptions.ConnectionError: Error 110 connecting to redis-server:6379. Connection timed out.Why This Happens
- 1.Network unreachable - Host not accessible
- 2.Firewall blocking - Port 6379 blocked
- 3.Redis not running - Server not started
- 4.Server overloaded - Too many pending connections
- 5.Wrong host/port - Incorrect connection parameters
- 6.DNS resolution - Hostname not resolving
Step 1: Check Redis Server Status
```bash # Check if Redis is running on server redis-cli ping # Should return PONG
# Check Redis process ps aux | grep redis-server
# Check Redis listening netstat -tlnp | grep 6379 # Should show redis-server listening on 6379
# Check Redis status (systemd) systemctl status redis
# Check Redis info redis-cli INFO server
# If Redis not running, start it sudo systemctl start redis # Or redis-server /etc/redis/redis.conf
# Check Redis logs tail -100 /var/log/redis/redis-server.log ```
Step 2: Test Network Connectivity
```bash # Ping the Redis server ping redis-server -c 5 # High latency or packet loss indicates network issue
# Check if port is reachable nc -zv redis-server 6379 # Should show: succeeded!
# Using telnet telnet redis-server 6379 # Should connect
# Test with timeout nc -w 5 -zv redis-server 6379 # 5 second timeout
# Check route to server traceroute redis-server # Identify network hops, find where connectivity breaks
# Check DNS resolution nslookup redis-server dig redis-server # Verify hostname resolves to correct IP
# Test from application server # Run these commands from the client machine ```
Step 3: Check Firewall Rules
```bash # Check iptables on Redis server iptables -L -n -v | grep 6379
# Allow Redis port iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
# For specific client IP iptables -I INPUT -s 192.168.1.100 -p tcp --dport 6379 -j ACCEPT
# Save iptables iptables-save > /etc/iptables/rules.v4
# Using ufw ufw status ufw allow 6379/tcp ufw allow from 192.168.1.100 to any port 6379
# Check firewalld (CentOS/RHEL) firewall-cmd --list-all firewall-cmd --add-port=6379/tcp --permanent firewall-cmd --reload
# Cloud firewall (AWS Security Groups, Azure NSG, GCP Firewall) # Ensure port 6379 allowed inbound
# Check if connection blocked # tcpdump on server tcpdump -i any port 6379 -nn # Watch for incoming connection attempts ```
Step 4: Check Redis Connection Limits
```bash # Check max clients setting redis-cli CONFIG GET maxclients # Default: 10000
# Check current connected clients redis-cli CLIENT LIST | wc -l
# Check client count redis-cli INFO clients # connected_clients: number
# If too many clients, connections are rejected redis-cli INFO clients | grep rejected # rejected_connections: number
# Increase max clients if needed redis-cli CONFIG SET maxclients 20000
# In redis.conf maxclients 20000
# Check if connections are idle redis-cli CLIENT LIST | grep -c idle= ```
Step 5: Increase Client Timeout Settings
```python # Python redis-py - increase timeout import redis
r = redis.Redis( host='redis-server', port=6379, socket_timeout=10, # Socket read/write timeout (seconds) socket_connect_timeout=10, # Connection timeout (seconds) retry_on_timeout=True # Retry on timeout ) ```
```java // Java Jedis - configure timeout Jedis jedis = new Jedis("redis-server", 6379, 10000); // 10 second timeout
// JedisPool with timeout JedisPoolConfig poolConfig = new JedisPoolConfig(); JedisPool pool = new JedisPool( poolConfig, "redis-server", 6379, 10000 // timeout in ms ); ```
// Java Lettuce (async client)
RedisClient client = RedisClient.create(
RedisURI.create("redis-server", 6379)
.withTimeout(Duration.ofSeconds(10))
);// Go redigo
pool := &redis.Pool{
Dial: func() (redis.Conn, error) {
return redis.Dial(
"tcp",
"redis-server:6379",
redis.DialConnectTimeout(10*time.Second),
redis.DialReadTimeout(10*time.Second),
redis.DialWriteTimeout(10*time.Second),
)
},
}Step 6: Configure Redis Server Timeout
```bash # Check current timeout redis-cli CONFIG GET timeout # Default: 0 (never timeout idle clients)
# Set timeout for idle clients redis-cli CONFIG SET timeout 300 # Disconnect idle clients after 300 seconds
# In redis.conf timeout 300
# This helps free up connections from idle clients # But ensure application reconnects properly
# Check tcp-keepalive redis-cli CONFIG GET tcp-keepalive # Default: 300
# Enable tcp-keepalive to detect dead connections redis-cli CONFIG SET tcp-keepalive 60
# In redis.conf tcp-keepalive 60 ```
Step 7: Use Connection Pooling
```python # Python redis-py connection pool import redis
pool = redis.ConnectionPool( host='redis-server', port=6379, max_connections=50, socket_timeout=10, socket_connect_timeout=10 )
r = redis.Redis(connection_pool=pool)
# Pool manages connections efficiently # Reuses connections instead of creating new ones ```
```java // Java Jedis connection pool JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(50); // Max connections poolConfig.setMaxIdle(20); // Max idle connections poolConfig.setMinIdle(5); // Min idle connections poolConfig.setTestWhileIdle(true); // Test idle connections poolConfig.setMaxWaitMillis(5000); // Wait time for connection
JedisPool pool = new JedisPool(poolConfig, "redis-server", 6379, 5000);
// Use pool try (Jedis jedis = pool.getResource()) { jedis.set("key", "value"); } ```
Step 8: Check Server Resource Load
```bash # Check Redis server load redis-cli INFO stats # instantaneous_ops_per_sec: operations per second # total_commands_processed: total commands
# Check memory usage redis-cli INFO memory | grep used_memory_human
# Check slow log redis-cli SLOWLOG GET 10 # Long-running commands blocking server
# Check CPU on server top -p $(pgrep redis-server)
# Check disk I/O iostat -x 1 5
# If server overloaded: # - Move to larger server # - Optimize queries # - Enable pipelining # - Split data to multiple Redis instances
# Check system resources redis-cli INFO stats | grep -E "instantaneous|blocked" ```
Step 9: Configure TCP Backlog
```bash # Check tcp-backlog setting redis-cli CONFIG GET tcp-backlog # Default: 511
# Increase for high connection rates redis-cli CONFIG SET tcp-backlog 1024
# In redis.conf tcp-backlog 1024
# Also increase system TCP backlog sudo sysctl -w net.core.somaxconn=1024 sudo sysctl -w net.ipv4.tcp_max_syn_backlog=1024
# Permanent in /etc/sysctl.conf net.core.somaxconn = 1024 net.ipv4.tcp_max_syn_backlog = 1024
# Apply sudo sysctl -p
# Restart Redis sudo systemctl restart redis ```
Step 10: Enable Redis Sentinel for HA
```bash # If connection timeouts are frequent, use Sentinel # Sentinel provides automatic failover
# Sentinel configuration # sentinel.conf port 26379 sentinel monitor mymaster redis-server 6379 2 sentinel down-after-milliseconds mymaster 30000 sentinel failover-timeout mymaster 180000 sentinel parallel-syncs mymaster 1
# Start Sentinel redis-sentinel /etc/redis/sentinel.conf
# Client configuration for Sentinel # Python: from redis.sentinel import Sentinel sentinel = Sentinel([('sentinel1', 26379), ('sentinel2', 26379)]) master = sentinel.master_for('mymaster') slave = sentinel.slave_for('mymaster')
# Sentinel handles connection failures # Automatically reconnects to new master on failover ```
Connection Timeout Diagnostic Checklist
| Check | Command | Expected |
|---|---|---|
| Redis running | redis-cli ping | PONG |
| Port reachable | nc -zv host 6379 | succeeded |
| Firewall allows | iptables -L | 6379 ACCEPT |
| Max clients | CONFIG GET maxclients | > connected |
| Timeout config | CONFIG GET timeout | Appropriate value |
| Server load | INFO stats | Normal ops/sec |
Verify the Fix
```bash # After addressing timeout causes
# 1. Test connection redis-cli -h redis-server ping # Should return PONG immediately
# 2. Test from application machine redis-cli -h redis-server -p 6379 INFO server
# 3. Monitor connection latency redis-cli -h redis-server --latency # Shows connection latency histogram
# 4. Check client connections redis-cli -h redis-server CLIENT LIST # Should show connections
# 5. Test application connection # Application should connect without timeout
# 6. Monitor connection stats redis-cli INFO clients # rejected_connections should not increase
# 7. Check network stability ping redis-server -c 100 # Low packet loss, consistent latency ```
Related Issues
- [Fix Redis Connection Refused](/articles/fix-redis-connection-refused)
- [Fix Redis Authentication Failed](/articles/fix-redis-authentication-failed)
- [Fix Redis High Latency](/articles/fix-redis-high-latency)