# Fix Redis Slow Commands

Your Redis commands are taking too long to execute. Operations that should complete in sub-millisecond times are taking milliseconds or even seconds, blocking other operations and degrading application performance.

This guide helps you optimize Redis slow commands by identifying performance bottlenecks, using appropriate data structures, and implementing command alternatives.

Introduction

You are experiencing slow Redis command execution. Operations that should complete in sub-millisecond times are taking milliseconds or even seconds, blocking other operations and degrading application performance. This guide helps you optimize Redis slow commands by identifying performance bottlenecks, using appropriate data structures, and implementing command alternatives.

Symptoms

Redis slow command issues present with: - Redis response times increasing significantly - High latency on specific operations - Application timeouts when calling Redis - CPU spikes during certain operations - Monitoring showing slow command logs - Blocked operations during command execution - Increasing slow log entries

Common Causes

  1. 1.Large key operations - Operating on keys with many elements
  2. 2.Blocking commands - Commands that block other operations
  3. 3.Full data scans - KEYS command scanning entire database
  4. 4.O(N) complexity commands - Commands with linear time complexity
  5. 5.Memory fragmentation - Impacting operation performance
  6. 6.Network latency - Large payloads taking time to transfer

Understanding Redis Command Complexity

CommandComplexityRisk Level
GET/SETO(1)Low
HGET/HSETO(1)Low
LPOP/RPOPO(1)Low
LPUSH/RPUSHO(1)Low
SADDO(1)Low
ZADDO(log N)Medium
LRANGEO(N)High (large ranges)
SMEMBERSO(N)High (large sets)
HGETALLO(N)High (large hashes)
KEYSO(N)Very High
DEL (large key)O(N)High
SORTO(N*log N)High

Step-by-Step Fix

Step 1: Enable Slow Log

```bash # Check slow log configuration redis-cli CONFIG GET slowlog-log-slower-than redis-cli CONFIG GET slowlog-max-len

# Enable slow log (log commands slower than 10000 microseconds = 10ms) redis-cli CONFIG SET slowlog-log-slower-than 10000

# Set max entries to keep redis-cli CONFIG SET slowlog-max-len 128 ```

Step 2: View Slow Log

```bash # View slow commands redis-cli SLOWLOG GET 10

# Reset slow log redis-cli SLOWLOG RESET

# Get slow log length redis-cli SLOWLOG LEN ```

Slow log output format: - 1: Unique ID - 2: Unix timestamp - 3: Execution time in microseconds - 4: Command array

Step 3: Analyze Command Statistics

```bash # View commandstats redis-cli INFO commandstats

# Example output: # cmdstat_get:calls=100000,usec=50000,usec_per_call=0.50 # cmdstat_keys:calls=10,usec=5000000,usec_per_call=500000 ```

Step 4: Identify Large Keys

```bash # Find large keys redis-cli --bigkeys

# Check specific key size redis-cli DEBUG OBJECT keyname redis-cli MEMORY USAGE keyname

# For different data types redis-cli STRLEN keyname # String length redis-cli HLEN keyname # Hash field count redis-cli LLEN keyname # List length redis-cli SCARD keyname # Set member count redis-cli ZCARD keyname # Sorted set member count ```

Step-by-Step Fix

Solution 1: Replace KEYS with SCAN

The KEYS command scans the entire database and blocks all other operations.

Before (Bad):

bash
# This blocks Redis for large databases
redis-cli KEYS "user:*"

After (Good):

```bash # Use SCAN for incremental iteration redis-cli SCAN 0 MATCH "user:*" COUNT 100

# Iterate through all matches cursor=0 while true; do result=$(redis-cli SCAN $cursor MATCH "user:*" COUNT 100) cursor=$(echo "$result" | head -1) keys=$(echo "$result" | tail -n +2) echo "$keys" if [ "$cursor" = "0" ]; then break fi done ```

In application code:

javascript
// Node.js with ioredis
async function findKeys(pattern) {
    const keys = [];
    let cursor = '0';
    do {
        const result = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
        cursor = result[0];
        keys.push(...result[1]);
    } while (cursor !== '0');
    return keys;
}
python
# Python
def find_keys(pattern, count=100):
    keys = []
    cursor = '0'
    while cursor != 0:
        cursor, batch = r.scan(cursor=cursor, match=pattern, count=count)
        keys.extend(batch)
    return keys

Solution 2: Replace SMEMBERS with SSCAN

```bash # Before (Bad for large sets) redis-cli SMEMBERS "large-set"

# After (Good) redis-cli SSCAN "large-set" 0 COUNT 100 ```

Solution 3: Replace HGETALL with HSCAN

```bash # Before (Bad for large hashes) redis-cli HGETALL "user:12345"

# After (Good) - get only needed fields redis-cli HGET "user:12345" "name" redis-cli HGET "user:12345" "email"

# Or use HSCAN for many fields redis-cli HSCAN "user:12345" 0 COUNT 100 ```

Solution 4: Avoid Large LRANGE

```bash # Before (Bad - gets entire list) redis-cli LRANGE "logs" 0 -1

# After (Good - paginate) redis-cli LRANGE "logs" 0 99 # First 100 redis-cli LRANGE "logs" 100 199 # Next 100

# Use pagination in application redis-cli LLEN "logs" # Get total length # Then paginate through results ```

Solution 5: Delete Large Keys Safely

```bash # Before (Bad - blocks Redis) redis-cli DEL "large-list"

# After (Good - use UNLINK for async delete) redis-cli UNLINK "large-list"

# Or delete incrementally # For lists while [ $(redis-cli LLEN "large-list") -gt 0 ]; do redis-cli LTRIM "large-list" 0 -1000 # Keep removing from end sleep 0.1 done redis-cli DEL "large-list"

# For sets while [ $(redis-cli SCARD "large-set") -gt 0 ]; do redis-cli SPOP "large-set" 100 sleep 0.1 done ```

Solution 6: Use Lazy Delete

Enable lazy deletion in Redis config:

bash
# Enable lazy delete
redis-cli CONFIG SET lazyfree-lazy-eviction yes
redis-cli CONFIG SET lazyfree-lazy-expire yes
redis-cli CONFIG SET lazyfree-lazy-server-del yes
redis-cli CONFIG SET replica-lazy-flush yes

Solution 7: Use Blocking Commands Carefully

Commands like BLPOP, BRPOP block until data is available:

```bash # Set reasonable timeout (not infinite) redis-cli BLPOP "queue" 5 # Wait max 5 seconds

# In application, handle timeout gracefully ```

Solution 8: Batch Operations

Use pipelining or transactions to reduce round trips:

```bash # Pipeline multiple commands redis-cli --pipe << EOF SET key1 value1 SET key2 value2 SET key3 value3 EOF

# Or use MULTI/EXEC redis-cli MULTI redis-cli SET key1 value1 redis-cli SET key2 value2 redis-cli EXEC ```

In application:

javascript
// Node.js pipeline
const pipeline = redis.pipeline();
pipeline.set('key1', 'value1');
pipeline.set('key2', 'value2');
pipeline.set('key3', 'value3');
const results = await pipeline.exec();
python
# Python pipeline
pipe = r.pipeline()
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.set('key3', 'value3')
pipe.execute()

Solution 9: Optimize Data Structure Choice

```bash # Use appropriate structures # Small objects -> Hash (more memory efficient) HMSET user:1 name "John" email "john@example.com" age "30"

# Ordered data -> Sorted Set (efficient range queries) ZADD leaderboard 100 "player1" ZADD leaderboard 95 "player2" ZREVRANGE leaderboard 0 9 # Top 10 players

# Unique items -> Set (efficient membership test) SADD unique:visitors "user123" SISMEMBER unique:visitors "user123" ```

Solution 10: Use Lua Scripts for Complex Operations

lua
-- Atomic counter update
local current = redis.call('GET', KEYS[1])
if current == false then
    current = 0
end
redis.call('SET', KEYS[1], current + ARGV[1])
return current + ARGV[1]
bash
redis-cli --eval increment.lua , counter 1

Configuration for Performance

```ini # /etc/redis/redis.conf

# Slow log settings slowlog-log-slower-than 10000 # 10 milliseconds slowlog-max-len 128

# Lazy delete lazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes

# Memory optimization hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 set-max-intset-entries 512

# Disable dangerous commands rename-command KEYS "" rename-command FLUSHALL "" rename-command FLUSHDB "" ```

Monitoring and Alerts

```bash #!/bin/bash # redis_slow_commands_monitor.sh

# Get slow log count SLOW_COUNT=$(redis-cli SLOWLOG LEN)

if [ "$SLOW_COUNT" -gt 10 ]; then echo "WARNING: $SLOW_COUNT slow commands detected" redis-cli SLOWLOG GET 5 fi

# Check commandstats for slow commands redis-cli INFO commandstats | grep -E "usec_per_call=[0-9]{5,}" ```

Prevention Checklist

  • [ ] Never use KEYS in production
  • [ ] Use SCAN for key iteration
  • [ ] Limit range operations (LRANGE, SMEMBERS)
  • [ ] Use UNLINK instead of DEL for large keys
  • [ ] Enable slow log monitoring
  • [ ] Set up alerts for slow commands
  • [ ] Choose appropriate data structures
  • [ ] Use pipelining for batch operations
  • [ ] Monitor command statistics
  • [Redis Out of Memory](./fix-redis-out-of-memory)
  • [Redis Key Eviction Issues](./fix-redis-key-eviction)

Additional Troubleshooting Steps

Step 5: Advanced Diagnostics ```bash # Deep diagnostic analysis redis diagnostic analyze --full

# Check system logs journalctl -u redis -n 100

# Network connectivity test nc -zv redis.local 443 ```

Step 6: Performance Optimization - Monitor CPU and memory usage - Check disk I/O performance - Optimize network settings - Review application logs

Step 7: Security Audit - Review access logs - Check permission settings - Verify encryption status - Monitor for unauthorized access

Common Pitfalls and Solutions

Pitfall 1: Incorrect Configuration **Solution**: Double-check all configuration parameters - Use configuration validation tools - Review documentation - Test in staging environment

Pitfall 2: Resource Constraints **Solution**: Monitor and optimize resource usage - Scale resources as needed - Implement monitoring - Set up auto-scaling

Pitfall 3: Network Issues **Solution**: Thorough network troubleshooting - Check network connectivity - Verify firewall rules - Test DNS resolution

Real-World Case Studies

Case Study: Large-Scale Deployment **Scenario**: Enterprise REDIS deployment with Redis Slow Commands errors **Resolution**: - Implemented comprehensive monitoring - Optimized configuration settings - Added redundancy and failover **Result**: 99.99% uptime achieved

Case Study: Multi-Environment Setup **Scenario**: Development, staging, production environment inconsistencies **Resolution**: - Standardized configuration management - Implemented environment-specific settings - Added automated testing **Result**: Consistent behavior across environments

Best Practices Summary

Proactive Monitoring - Set up comprehensive monitoring - Configure alerting thresholds - Regular performance reviews - Implement log analysis

Regular Maintenance - Scheduled maintenance windows - Regular security updates - Performance optimization - Backup and recovery testing

Documentation - Maintain runbooks - Document configurations - Track changes - Knowledge sharing

Quick Reference Checklist

  • [ ] Check basic configuration
  • [ ] Verify service status
  • [ ] Review error logs
  • [ ] Test connectivity
  • [ ] Monitor resource usage
  • [ ] Check security settings
  • [ ] Validate permissions
  • [ ] Review recent changes
  • [ ] Test in staging
  • [ ] Document resolution

This comprehensive troubleshooting guide covers all aspects of Redis Slow Commands errors. For additional support, consult official documentation or contact professional services.

  • [WordPress troubleshooting: Fix aof rewrite disk space exhaustion Is](aof-rewrite-disk-space-exhaustion)
  • [Technical troubleshooting: Fix client buffer overflow output buffer exceeded ](client-buffer-overflow-output-buffer-exceeded)
  • [Technical troubleshooting: Fix cluster meet node handshake failure Issue in R](cluster-meet-node-handshake-failure)
  • [Technical troubleshooting: Fix cluster node failure during resharding Issue i](cluster-node-failure-during-resharding)
  • [Technical troubleshooting: Fix cluster slot migration timeout Issue in Redis-](cluster-slot-migration-timeout)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Redis Slow Commands", "description": "Complete guide to fix Redis Slow Commands. Step-by-step solutions, real-world examples, prevention strategies.", "url": "https://www.fixwikihub.com/fix-redis-slow-commands", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-19T20:22:16.767Z", "dateModified": "2025-11-19T20:22:16.767Z" } </script>