Skip to content

Performance Issues

Solutions for latency and throughput problems.

Problem: High Latency

Symptoms

  • Redis operations taking >10ms
  • Increased p99 latency
  • Slow API responses

Diagnosis

bash
# Check Redis latency
redis-cli --latency

# Check slow log
redis-cli SLOWLOG GET 10

# Check network latency
redis-cli DEBUG SLEEP 0 && time redis-cli PING
yaml
# Operation latency p99
histogram_quantile(0.99, rate(redisx_operation_duration_seconds_bucket[5m]))

Solutions

CauseSolution
Network latencyMove Redis closer to app
Large valuesCompress or split data
Expensive commandsAvoid KEYS, use SCAN
Connection pool exhaustedIncrease pool size
Redis overloadedScale up or out

Problem: Connection Pool Exhaustion

Symptoms

  • "Cannot acquire connection" errors
  • Requests timing out waiting for connection
  • Spiky latency under load

Diagnosis

yaml
# Pool utilization
redisx_pool_active_connections / redisx_pool_max_connections

# Pending requests
redisx_pool_pending_requests

Solutions

typescript
// Increase pool size
RedisModule.forRoot({
  clients: {
    host: 'localhost',
    pool: {
      min: 10,
      max: 50,  // Increase from default
    },
  },
})
CauseSolution
Pool too smallIncrease pool.max
Connections not releasedCheck for connection leaks
Slow commandsOptimize or add timeout

Problem: Memory Pressure

Symptoms

  • Redis memory near max
  • Evictions increasing
  • Slow operations

Diagnosis

bash
# Memory info
redis-cli INFO memory

# Find big keys
redis-cli --bigkeys

# Memory usage by key
redis-cli MEMORY USAGE "cache:big-key"

Solutions

CauseSolution
TTL too longReduce TTL
Large valuesCompress data
Too many keysReduce cardinality
No eviction policySet maxmemory-policy
bash
# Set eviction policy
redis-cli CONFIG SET maxmemory-policy allkeys-lru

Problem: Slow Commands

Symptoms

  • Specific operations are slow
  • SLOWLOG shows patterns
  • High CPU on Redis

Diagnosis

bash
# Check slow commands
redis-cli SLOWLOG GET 20

Production Risk

redis-cli MONITOR impacts performance significantly. Never use in production.

Solutions

Slow CommandAlternative
KEYS *SCAN with cursor
SMEMBERS large setSSCAN
HGETALL large hashHSCAN or specific HGET
Lua with many keysBreak into smaller operations
typescript
// Non-blocking with SCAN
const keys = [];
let cursor = '0';
do {
  const [newCursor, batch] = await redis.scan(cursor, 'MATCH', 'user:*', 'COUNT', 100);
  cursor = newCursor;
  keys.push(...batch);
} while (cursor !== '0');
typescript
// Blocks Redis - never use in production
await redis.keys('user:*');

Problem: Throughput Bottleneck

Symptoms

  • Can't scale beyond certain RPS
  • Redis CPU at 100%
  • Adding app instances doesn't help

Diagnosis

bash
# Check Redis stats
redis-cli INFO stats

# Check CPU
redis-cli INFO cpu

Solutions

CauseSolution
Single-threaded RedisUse Redis Cluster
CPU-intensive commandsOptimize commands
Too many round tripsUse pipelining
typescript
// Single round trip with pipeline
const pipeline = redis.pipeline();
pipeline.set('key1', 'val1');
pipeline.set('key2', 'val2');
pipeline.set('key3', 'val3');
await pipeline.exec();
typescript
// Multiple round trips - inefficient
await redis.set('key1', 'val1');
await redis.set('key2', 'val2');
await redis.set('key3', 'val3');

Problem: Cold Start Latency

Symptoms

  • First requests after deploy are slow
  • Cache miss spike after restart
  • Database overwhelmed on deploy

Solutions

typescript
// Warm cache on startup
@Injectable()
export class CacheWarmer implements OnModuleInit {
  async onModuleInit() {
    // Pre-populate critical cache
    await this.warmPopularProducts();
    await this.warmFeatureFlags();
  }

  private async warmPopularProducts() {
    const products = await this.db.getPopularProducts(100);
    for (const product of products) {
      await this.cache.set(`product:${product.id}`, product, { ttl: 3600 });
    }
  }
}

Performance Checklist

Before Going Live

Verify these items for optimal Redis performance:

ItemStatus
Connection pool sized appropriately
TTLs not too long or short
No KEYS commands in production
Large values compressed
Pipelining used where possible
Redis topology matches workload
Monitoring in place

Next Steps

Released under the MIT License.