Redis interview questions covering caching, data structures, TTL, persistence, pub/sub, streams, locks, rate limiting, and performance.
Redis is an in-memory data store commonly used as a cache, message broker, session store, queue, rate limiter, leaderboard engine, and fast key-value database. It supports rich data structures such as strings, hashes, lists, sets, sorted sets, streams, bitmaps, HyperLogLogs, and geospatial indexes.
Redis is fast because it keeps data primarily in memory, uses efficient data structures, runs most commands in a single-threaded event loop, and avoids disk I/O on the request path for ordinary operations. Real performance still depends on network latency, command complexity, payload size, persistence settings, and hot keys.
Strings are the simplest Redis value type. They can store text, JSON, counters, tokens, serialized objects, or binary data. Strings support atomic increments, TTLs, and common cache operations.
SET user:1:name "Asha"
GET user:1:name
INCR page:view:home
SET session:abc "user-1" EX 3600
Hashes store field-value pairs under one key. They are useful for small objects such as user profiles, product metadata, feature flags, and session attributes. Hashes let you update one field without rewriting the whole object.
HSET user:1 name "Asha" email "asha@example.com"
HGET user:1 email
HGETALL user:1
Lists are ordered collections of strings with efficient push and pop operations at both ends. They are useful for simple queues, recent activity feeds, and ordered buffers. For robust consumer groups, Redis Streams are often a better choice.
LPUSH jobs "send-email:1"
RPOP jobs
BRPOP jobs 5
Sets store unique unordered members. They are useful for membership checks, tags, unique visitors, permissions, and set operations such as union, intersection, and difference.
SADD post:1:tags redis cache database
SISMEMBER post:1:tags redis
SINTER user:1:roles admin:roles
Sorted sets store unique members with numeric scores. They are ideal for leaderboards, rankings, priority queues, delayed jobs, and time-ordered indexes.
ZADD leaderboard 980 user:1 750 user:2
ZREVRANGE leaderboard 0 9 WITHSCORES
ZRANK leaderboard user:2
Streams are append-only log-like data structures for event and message processing. They support consumer groups, acknowledgements, pending entries, and replay. Streams are useful when Pub/Sub is too ephemeral and lists are too limited.
XADD orders * id 101 status paid
XGROUP CREATE orders workers $ MKSTREAM
XREADGROUP GROUP workers worker-1 COUNT 10 STREAMS orders >
HyperLogLog estimates the number of unique elements using very little memory. It is useful for approximate counts such as daily unique visitors, unique searches, or unique active users. The tradeoff is that it is approximate, not exact.
PFADD visitors:2026-06-03 user:1 user:2 user:3
PFCOUNT visitors:2026-06-03
Bitmaps use string values as compact bit arrays. They are useful for boolean flags at scale, such as daily active users, feature participation, attendance, or simple yes/no tracking by numeric ID.
SETBIT active:2026-06-03 42 1
GETBIT active:2026-06-03 42
BITCOUNT active:2026-06-03
Pub/Sub sends messages to currently subscribed clients and does not store them for later delivery. Streams persist messages and support replay, consumer groups, and acknowledgements. Use Pub/Sub for live notifications and Streams for more reliable event processing.
TTL, or time to live, defines when a key expires automatically. It is essential for caches, sessions, OTPs, locks, and rate limits. Missing TTLs can cause memory growth, while TTLs that are too short can create cache misses and database load.
SET otp:user:1 492011 EX 300
TTL otp:user:1
EXPIRE cache:products 600
Cache invalidation is the process of removing or updating cached data when the source of truth changes. Common approaches include TTL expiry, explicit delete on writes, versioned keys, event-driven invalidation, and write-through updates. It is hard because stale data can cause incorrect user behavior.
In cache-aside, the application checks Redis first. On a miss, it reads from the database, stores the result in Redis with a TTL, and returns it. On writes, the application updates the database and invalidates or refreshes the cache.
value = GET cache:user:1
if value is missing:
value = SELECT user FROM database
SET cache:user:1 value EX 300
In write-through caching, writes update the cache and the database as part of the write path. It can keep cache data fresher, but it adds latency to writes and requires careful failure handling if one write succeeds and the other fails.
Write-behind caching writes to Redis first and asynchronously persists to the database later. It can improve write latency but risks data loss or inconsistency if Redis fails before persistence completes. It should be used only when durability requirements are understood.
Eviction policies decide what Redis removes when maxmemory is reached. Examples include noeviction, allkeys-lru, volatile-lru, allkeys-lfu, volatile-ttl, and random variants. Choose based on whether Redis is a cache, session store, queue, or durable-like data store.
CONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru
LRU evicts keys that were least recently used. LFU evicts keys used least frequently. LRU works well when recent access predicts future access, while LFU helps when a smaller set of keys is consistently popular over time.
RDB persistence saves point-in-time snapshots of Redis data to disk. It is compact and good for backups, but data written after the last snapshot can be lost during a crash. Snapshot frequency affects durability and resource usage.
AOF, or Append Only File, logs write commands so Redis can replay them after restart. It usually provides better durability than RDB depending on fsync settings, but it can use more disk and requires rewrite management.
RDB is snapshot-based, compact, and fast to restore, but may lose recent writes. AOF records write operations and can reduce data loss, but costs more disk and write overhead. Many production setups use both when Redis data has recovery value.
Replication copies data from a primary Redis instance to one or more replicas. It helps with read scaling and high availability. Replication is asynchronous in common setups, so replicas can lag and may not have the latest writes.
Sentinel monitors Redis primaries and replicas, detects failures, performs automatic failover, and provides service discovery for clients. It is used for high availability in non-clustered Redis deployments.
Redis Cluster shards data across multiple primary nodes using hash slots. It provides horizontal scaling and high availability with replicas. Clients must be cluster-aware because keys may live on different nodes and multi-key operations have slot limitations.
Redis Cluster maps keys to 16,384 hash slots. Each primary node owns a range of slots. Keys with the same hash tag, such as user:{42}:profile and user:{42}:settings, can be forced into the same slot for multi-key operations.
MGET user:{42}:profile user:{42}:settings
Redis transactions use MULTI, EXEC, DISCARD, and WATCH. Commands queued after MULTI execute sequentially when EXEC runs. Redis transactions do not roll back like SQL transactions, so validation and idempotency matter.
MULTI
INCR account:1:balance
DECR account:2:balance
EXEC
WATCH provides optimistic locking. If a watched key changes before EXEC, the transaction is aborted. It is useful for compare-and-set style updates when multiple clients may modify the same key.
WATCH inventory:item:1
GET inventory:item:1
MULTI
DECR inventory:item:1
EXEC
Lua scripts run atomically inside Redis. They are useful when multiple commands must be executed as one atomic operation, such as rate limiting or conditional updates. Keep scripts short because long scripts block other commands.
EVAL "return redis.call('INCR', KEYS[1])" 1 counter:login
A basic lock uses SET with NX and EX so the key is created only if absent and expires automatically. The value should be a unique token, and unlock should delete only if the token matches. Locks must account for timeouts, clock assumptions, and operation duration.
SET lock:order:123 unique-token NX EX 30
Redlock is a Redis-based distributed locking algorithm that tries to acquire locks across multiple independent Redis nodes. It is debated for some correctness-sensitive systems. In interviews, explain the tradeoff: it may be acceptable for efficiency locks, but critical correctness often needs stronger coordination systems.
A simple fixed-window limiter increments a key and sets an expiry. More accurate designs use sliding windows with sorted sets or token buckets. Rate limiting must define identity, window, limit, burst behavior, and what happens during Redis failure.
INCR rate:user:42:minute
EXPIRE rate:user:42:minute 60
Leaderboards are commonly built with sorted sets. The member is the player or entity, and the score is the ranking value. Redis can return top players, player rank, and nearby competitors efficiently.
ZADD game:rank 1500 player:1
ZREVRANGE game:rank 0 9 WITHSCORES
ZREVRANK game:rank player:1
Redis is often used for sessions because it is fast and supports TTLs. Store session data under a session key with an expiration. Use secure session IDs, reasonable TTLs, encryption where needed, and plan for Redis outages.
SET session:abc123 "user_id=42" EX 3600
A hot key is accessed far more frequently than other keys, causing one Redis node or shard to become a bottleneck. Mitigations include local caching, key splitting, request coalescing, replication for reads, or redesigning data access patterns.
Pipelining sends multiple commands to Redis without waiting for each response one by one. It reduces network round trips and improves throughput. It does not make commands transactional; it is a performance technique.
PIPELINE
SET key:1 a
SET key:2 b
GET key:1
EXECUTE PIPELINE
The slow log records commands that exceed a configured execution time. It helps find expensive commands, large payload operations, and blocking scripts. It measures execution time inside Redis, not network latency.
SLOWLOG GET 10
CONFIG SET slowlog-log-slower-than 10000
Memory fragmentation happens when allocated memory is larger than the memory Redis actively uses for data. It can be caused by allocator behavior, churn, and workload patterns. Monitor used_memory, used_memory_rss, and mem_fragmentation_ratio.
Use predictable names with namespaces and identifiers, such as user:42:profile or cache:product:123. Good naming helps debugging, avoids collisions, and supports targeted invalidation. Avoid extremely long keys and avoid patterns that create accidental hot spots.
KEYS searches the entire keyspace and can block Redis on large datasets. SCAN iterates incrementally and is safer for production introspection. SCAN may return duplicates and is not a snapshot, so clients must handle iteration carefully.
SCAN 0 MATCH cache:user:* COUNT 100
Connection pooling reuses Redis connections instead of opening one for every operation. It reduces overhead and protects Redis from too many clients. Pool size should match application concurrency, Redis capacity, and timeout behavior.
Monitor memory usage, evictions, hit rate, command latency, connected clients, blocked clients, replication lag, keyspace size, expired keys, rejected connections, CPU, persistence failures, and slowlog entries. Metrics should be tied to user-facing latency and error rates.
Cache hit ratio is the percentage of cache lookups served from Redis instead of the source database or service. A low hit ratio may indicate bad keys, short TTLs, ineffective caching strategy, or a workload that is not cache-friendly.
A cache stampede happens when many requests miss the same key at once and all hit the database. Mitigations include request coalescing, locks, stale-while-revalidate, TTL jitter, early refresh, and warming critical keys.
TTL jitter adds random variation to expiration times so many keys do not expire simultaneously. It reduces synchronized cache misses and protects downstream databases from sudden load spikes.
SET cache:item:1 "value" EX 327
# choose 300 seconds plus random 0-60 seconds
ACLs control which users can run which commands and access which key patterns. They are useful for separating app, admin, read-only, and automation access. Use ACLs with TLS, network controls, and strong secret management.
ACL SETUSER app on >strong-password ~app:* +get +set +del
Secure Redis by avoiding public exposure, using authentication or ACLs, enabling TLS where needed, restricting network access, disabling dangerous commands when appropriate, rotating credentials, monitoring access, and never treating Redis as safe just because it is fast.
Risks include assuming cache data is durable, misconfigured AOF fsync, no tested restore process, disk full during persistence, slow fork operations for snapshots, and using Redis as the only source of truth without durability planning.
Common anti-patterns include using KEYS in production, storing huge values, missing TTLs for cache keys, using Redis as a relational database, no memory policy, no monitoring, overusing Lua scripts, unbounded lists or streams, and sharing one Redis instance across unrelated workloads without isolation.
Choose strings for simple values and counters, hashes for objects, sets for unique membership, sorted sets for ranking and time-score queries, lists for simple queues, streams for reliable event processing, and bitmaps or HyperLogLogs for specialized counting problems.
A strong demo uses cache-aside with clear key names, serialization, TTL, invalidation on writes, and metrics for hit ratio and latency. Explain what happens on cache miss, database failure, stale data, and Redis outage.
GET cache:product:123
# miss: read database
SET cache:product:123 '{"id":123,"name":"Keyboard"}' EX 600
DEL cache:product:123
Explore 500+ free tutorials across 20+ languages and frameworks.