Home / Databases / Redis

DatabasesHow-toIntermediate

Optimization: reducing Redis memory - data structures, compact encodings, TTLs and eviction policy

Redis keeps everything in RAM, so memory use is cost. Find what uses memory, store small objects in hashes with compact encodings, set TTLs on cache keys, choose the right eviction policy, watch fragmentation, and right-size the instance or cluster once usage is under control.

Deepak Bhardwaj3 min read

Applies toRedis 7.x and Valkey (self-managed), Azure Managed Redis / Azure Cache for Redis, Amazon ElastiCache, Redis Cloud

See what uses memory

redis-cli INFO memory | egrep "used_memory_human|used_memory_rss_human|mem_fragmentation_ratio|maxmemory_human|maxmemory_policy"
redis-cli --bigkeys          # largest keys per type (sampled)
redis-cli --memkeys          # keys by memory usage (Redis 7+)
redis-cli MEMORY USAGE user:1001
redis-cli MEMORY DOCTOR

Group keys by prefix (e.g. with a SCAN-based script) to see which feature or service owns the memory.

Store small objects efficiently

Instead of Use Why
One string key per field (user:1:name, user:1:email) One hash per object (HSET user:1 name ... email ...) Fewer keys, less per-key overhead
JSON strings for objects you update field by field Hashes (or RedisJSON where available) Update fields without rewriting the blob
Large sets of small integers Sets (intset encoding) or bitmaps Compact representation

Small hashes, lists, sets and sorted sets use compact encodings (listpack/intset) below thresholds:

redis-cli CONFIG GET hash-max-listpack-entries
redis-cli CONFIG GET hash-max-listpack-value
redis-cli OBJECT ENCODING user:1001

Raising thresholds slightly can save memory at some CPU cost; test before changing.

TTLs on cache data

# Keys without TTL in a sample (keyspace info shows counts per DB)
redis-cli INFO keyspace        # keys=..., expires=...

A large gap between keys and expires in a cache means many keys never expire. Set TTLs in application code (SET key value EX 3600), with some jitter to avoid mass expiry at the same moment.

Eviction policy

Policy Use
allkeys-lru / allkeys-lfu Pure cache; evict any key
volatile-lru / volatile-lfu / volatile-ttl Mix of cache keys (with TTL) and persistent keys (without)
noeviction Data store; writes fail when full (see the OOM post)

Fragmentation

  • mem_fragmentation_ratio well above 1.5 means RSS much larger than data.
  • Enable active defragmentation (activedefrag yes) where supported, or restart replicas/failover during a window.

Value size

  • Compress large values in the client (e.g. zstd/LZ4) if they're mostly read whole.
  • Avoid storing big blobs in Redis; store a reference and keep the blob in object storage.

Right-size after cleanup

Once memory is under control, check peak usage plus headroom for replication buffers, fork for persistence (copy-on-write), and growth. Then choose a smaller tier or fewer shards (check current service tiers).

Tip

Most Redis memory problems come from one or two key patterns. Find the biggest prefixes first; fixing them usually beats any configuration tweak.

Checklist

  • Memory usage by prefix and big keys known
  • Small objects stored as hashes with compact encodings
  • TTLs with jitter on cache keys
  • Eviction policy matches usage
  • Fragmentation monitored, defrag enabled where available
  • Instance right-sized with headroom