Redis performance work starts by separating server execution, network round trips, operating-system scheduling, persistence I/O, memory pressure, and client behavior. A fast average can hide blocking commands or eviction bursts. Establish an application latency objective, capture percentiles and errors, and change the smallest verified cause.
- Use
SLOWLOGand the latency monitor to identify server-side stalls; measure network and intrinsic host latency separately. - Bound work per command. Incremental scans and paged collection reads are safer than returning an entire large key, but they still consume total work.
- Inspect
INFO memory,MEMORY STATS,MEMORY USAGE, and actual key encodings before changing the data model. - Set
maxmemorywith room for replication and persistence overhead, then select an eviction policy from data semantics. - Use bounded pipelines to reduce round trips and test persistence, failover, and fork behavior with the same dataset.
Measure the latency layers
Record application p50/p95/p99 latency, timeouts, retries, connection establishment, and command mix. From a host near the application, redis-cli --latency helps measure the client-to-server path. On the Redis host, redis-cli --intrinsic-latency measures scheduler and virtualization latency without connecting to Redis; it is CPU intensive while running, so use a controlled diagnostic window.
redis-cli --latency -h cache.example.internal -p 6379
redis-cli --intrinsic-latency 30The slow log records command execution time on the server, excluding client network I/O. Choose its threshold from the service objective and expected command cost rather than copying a universal millisecond value.
CONFIG GET slowlog-log-slower-than
SLOWLOG LEN
SLOWLOG GET 20
CONFIG SET latency-monitor-threshold 25
LATENCY LATEST
LATENCY DOCTORCONFIG SET changes runtime state and may not persist across restart in every deployment. Manage lasting settings through the approved configuration or managed-service mechanism. Latency events can reveal command, fork, eviction, AOF, and other stalls that do not appear as one slow command.
Bound command work and response size
Redis command documentation includes algorithmic complexity. A command that is safe for a ten-element collection can block the command-processing path when the same key grows to millions of elements. Replace production KEYS with cursor-based SCAN, and replace unbounded HGETALL, SMEMBERS, or full-range operations with bounded access where the application can tolerate cursor semantics.
One call does limited work, but a complete iteration still traverses the keyspace and can return duplicates while data changes. Bound each batch, tolerate duplicates, and avoid launching many concurrent full scans.
For a large key that must be deleted, UNLINK removes the key from the keyspace and reclaims much of its memory asynchronously. Background freeing still consumes CPU and memory bandwidth; rate-limit bulk cleanup and observe latency.
Find big keys and hot keys safely
INFO memory
MEMORY STATS
MEMORY USAGE session:example SAMPLES 10
OBJECT ENCODING session:exampleredis-cli --bigkeys scans the keyspace and reports the largest sampled structures by type; --memkeys estimates memory. They can add load and do not produce a perfect global ranking. Run them in a controlled window or against a representative replica or snapshot, understanding that a replica diagnostic still consumes resources and can increase lag.
A big key creates long command responses, deletion work, replication bursts, and difficult cluster migration. A hot key concentrates request load even when it is small. Address them differently: split unbounded collections, page results, cap payloads, cache immutable hot data in clients where correctness allows, or redesign the key so traffic distributes without breaking required atomic operations.
Model memory from evidence
Redis memory includes keys and values, allocator fragmentation, client buffers, replication backlog and replicas, script/function state, and temporary copy-on-write pages during fork-based persistence. used_memory and resident set size answer different questions. A high fragmentation ratio after a large deletion is not by itself proof of a leak because allocators can retain reusable pages.
Small hashes, lists, sets, and sorted sets can use compact encodings such as listpack or intset while their entries remain within configured limits. That can be materially smaller, but crossing a threshold changes the representation. Do not raise thresholds broadly without measuring conversion latency and CPU.
CONFIG GET hash-max-listpack-entries
CONFIG GET hash-max-listpack-value
CONFIG GET zset-max-listpack-entries
CONFIG GET set-max-intset-entriesA hash is not automatically smaller than a JSON string for every object. Compare MEMORY USAGE, update patterns, serialization, and command count for the actual shape. Compact one logical object into a hash when field access and expiry semantics fit; avoid multiplying tiny top-level keys without measuring their key overhead.
Use TTLs as a retention contract
Set expiration when data has a real lifetime: cache entries, sessions, leases, or transient results. Prefer atomic write-plus-expiry commands such as SET ... EX when a separate EXPIRE could be missed. Add controlled jitter where many keys would otherwise expire at the same instant and stampede the backing database.
SET session:abc encrypted-value EX 3600
TTL session:abcDo not put a TTL on authoritative data merely to lower memory. Confirm refresh, invalidation, and failure behavior, and monitor the share of keys without expiration when the design expects one.
Set maxmemory and eviction from semantics
A maxmemory ceiling prevents user data from consuming memory without bound, but the process can use additional memory for fragmentation, buffers, replication, and persistence. Redis reports mem_not_counted_for_evict to help expose some excluded overhead. Size the host for peak dataset plus measured operational headroom, including fork copy-on-write during RDB or AOF rewrite.
| Policy family | Fit | Failure to plan for |
|---|---|---|
allkeys-lru / allkeys-lfu | All keys are disposable cache entries | Eviction changes hit rate and can overload the source of truth |
volatile-* | Only keys with TTL are eligible | If eligible keys are exhausted, writes can fail while non-expiring keys remain |
noeviction | Unexpected deletion is unacceptable | Memory-growing writes return errors at the limit; clients need backpressure and recovery |
Track evicted_keys, rejected connections, command errors, keyspace hits and misses, latency, and upstream load. No hit-ratio percentage is universally correct: calculate whether the cache reduces cost and latency for its workload.
Balance persistence and latency
RDB snapshots and AOF provide different durability and recovery characteristics. Fork, page copying, disk throughput, and fsync can affect latency. appendfsync everysec is a common tradeoff, not a zero-loss guarantee. Replication also does not replace backups or make acknowledged writes immune to failover loss.
Benchmark steady writes, snapshot creation, AOF rewrite, restart, replica resynchronization, and failover. Monitor latest_fork_usec, persistence status, copy-on-write bytes, disk latency, replication lag, and recovery time. Choose settings from the data-loss objective rather than enabling every mechanism by habit.
Reduce network and connection overhead
Reuse connections through a client appropriate to the application's concurrency model. Avoid an oversized pool that creates server file-descriptor and buffer pressure. Pipelining reduces round trips by sending commands without waiting for each reply, but the server must queue replies; use bounded batches and apply backpressure.
Multi-key atomicity and scripts need special care in Redis Cluster because keys must map to compatible slots. Hash tags can co-locate related keys, but an overused tag creates a hot slot. Measure slot distribution and failover behavior before committing to a key naming convention.
Production tuning loop
- Capture application latency, errors, command mix, memory, eviction, persistence, and replication under representative load.
- Use the slow log and latency monitor to classify the stall.
- Identify the key and command shape, not just the server-wide symptom.
- Test one bounded change in a replica, staging system, or controlled canary.
- Exercise persistence and failover after data-model or memory changes.
- Retain the change only when latency, memory, correctness, and recovery improve together.
Official primary sources
- Redis latency diagnosis
- Redis latency monitor
- Redis memory optimization
- Redis key eviction
- Redis pipelining
- Redis persistence
Working with JusDB on Redis performance
JusDB helps teams trace Redis latency to commands, keys, memory, persistence, or clients, then validate a bounded tuning change under production-shaped load.
Explore JusDB Redis services → | Talk to a database engineer