Redis Interview Questions and Answers
Data structures, persistence, expiry, pub/sub and caching patterns.
Whether you are preparing for entry-level Redis interview questions for freshers or senior software engineer interview questions addressing concurrency, scalability, and system architecture, this track provides peer-reviewed model answers with syntax walkthroughs, edge cases, and practical interview tips.
1 What are the Redis data structures and what is each used for? Easy
Redis exposes several core data types, each with tailored commands.
- Strings: counters, cached serialized objects and rate limiters using INCR and SETEX.
- Hashes: objects with fields, such as a user profile, via HSET and HGETALL.
- Lists: queues and stacks for simple job processing with LPUSH and BRPOP.
- Sets: unique membership and set operations such as intersections.
- Sorted sets: leaderboards and priority queues, ordered by score.
- Streams: append-only logs with consumer groups for event processing.
- Bitmaps, HyperLogLog and geospatial indexes: compact counting, cardinality estimation and location queries.
Choosing the right structure matters: a leaderboard in a sorted set is O(log N), while the same in a list would require scanning. Prefer one hash over many string keys for a single object to save memory.
2 What is a Redis sorted set and what are common use cases? Easy
A sorted set stores unique members, each with a floating-point score, kept ordered by score. Operations are O(log N), and you can query by rank or by score range.
ZADD leaderboard 1500 alice
ZADD leaderboard 1720 bob
ZINCRBY leaderboard 50 alice
ZREVRANGE leaderboard 0 9 WITHSCORES
ZRANGEBYSCORE leaderboard 1000 2000
Use cases:
- Leaderboards and rankings, reading the top N in order.
- Priority queues where the score is scheduled time.
- Rate limiting by counting events in a sliding window.
- Secondary indexes mapping a timestamp or weight to an id.
- Delayed jobs scored by execution time, polled with ZRANGEBYSCORE.
Members are unique, so adding an existing member updates its score rather than duplicating it. Small sorted sets use a compact list representation, giving excellent memory efficiency.
3 How does Redis persistence work with RDB and AOF? Medium
Redis offers two persistence mechanisms.
RDB takes point-in-time snapshots at configured intervals, for example save 900 1 snapshots after 900 seconds if at least one key changed. RDB files are compact and fast to load, which is good for backups and restarts, but a crash loses writes since the last snapshot.
AOF appends every write command to a log. With appendfsync everysec Redis fsyncs once per second, a good balance; always is slowest but safest; no lets the OS decide. AOF grows over time and is compacted by rewrite, and you can enable AOF and RDB together.
On restart Redis prefers AOF because it is usually more complete. For pure caches you may disable persistence entirely and rely on the source of truth. Always test the restore path, not just the backup.
4 Explain key expiry and eviction policies in Redis. Medium
You set a time to live with EXPIRE, SETEX or PEXPIRE. Redis removes expired keys lazily on access and also runs a background sampling cycle that actively deletes expired keys. Expiry is per key and works with any data type.
Eviction happens when memory reaches maxmemory. Policies include:
- noeviction: reject writes, best when data must not be lost.
- allkeys-lru and allkeys-lfu: evict least recently or least frequently used keys across all keys, best for caches.
- volatile-lru, volatile-lfu and volatile-ttl: evict only keys with a TTL.
- allkeys-random and volatile-random: random eviction.
LRU in Redis is approximate, sampling a few keys rather than tracking perfect order. LFU tracks access frequency and suits skewed workloads. Choose allkeys-lru for a general cache and volatile variants if some keys must persist. Monitor evicted_keys and hit rate.
5 What is the cache-aside pattern and how do you keep the cache consistent? Medium
In cache-aside the application checks the cache first. On a miss it reads from the database, writes the value into the cache with a TTL, and returns it. On writes, the common approach is to update the database and then invalidate the cache key.
def get_user(uid):
cached = redis.get(f"user:{uid}")
if cached:
return json.loads(cached)
user = db.get_user(uid)
redis.setex(f"user:{uid}", 300, json.dumps(user))
return user
Consistency pitfalls: updating the cache before the database, or racing concurrent writers, can leave stale data. Delete the cache on write and let the next read repopulate it, using a short TTL as a safety net. For stronger needs use versioned keys or write-through. The first request after invalidation always pays the database cost.
6 What is the difference between Redis Pub/Sub and Streams? Medium
Pub/Sub is fire-and-forget messaging. Publishers send to a channel and subscribers receive in real time, but messages are not stored. An offline subscriber misses them, and there is no acknowledgement or replay. It is simple and fast for live notifications where loss is acceptable.
Streams are a persistent, append-only log. Each entry has an id, and consumers can read ranges, replay history, and use consumer groups for at-least-once delivery with XACK acknowledgements. Pending entries can be claimed by another consumer if one fails, and XADD supports trimming with MAXLEN.
XADD orders * type "created" id 42
XREADGROUP GROUP workers c1 COUNT 10 BLOCK 5000 STREAMS orders >
Use Pub/Sub for ephemeral events and Streams for reliable event processing, audit logs or work queues that must survive restarts.
7 How do you prevent a cache stampede or thundering herd? Medium
A stampede happens when a popular key expires and many clients simultaneously hit the database to rebuild it. Several mitigations exist.
- Locking or mutex: only the first request rebuilds while others wait briefly or serve stale data, using SET NX with a short TTL as a rebuild lock.
- Probabilistic early expiration: refresh before expiry with random jitter so rebuilds spread out.
- Stale-while-revalidate: serve the expired value while one worker refreshes in the background.
- TTL jitter: add a random offset so many keys do not expire at once.
- Request coalescing: deduplicate concurrent misses for the same key in-process.
- Never expire hot keys, refreshing them with a scheduled job.
Combine TTL jitter with a rebuild lock for most read-heavy systems, and monitor hit rate and database load during incidents.
8 What are pipelining and transactions in Redis? Medium
Pipelining sends many commands in one network round trip without waiting for each reply, dramatically improving throughput for batch workloads since cost is dominated by round-trip time rather than execution.
pipe = redis.pipeline()
for k in keys:
pipe.get(k)
results = pipe.execute()
Transactions use MULTI and EXEC to queue commands and run them as one isolated step without interleaving from other clients. WATCH provides optimistic locking: if a watched key changes before EXEC, the transaction aborts and the client retries.
WATCH balance:1
MULTI
SET balance:1 100
EXEC
Redis transactions are not rollback based: if one queued command fails at runtime the others still run. Use Lua scripts when you need atomic read-modify-write logic executed server-side.
9 How do you implement a distributed lock with Redis? Hard
A common implementation is SET key value NX PX ttl. NX sets the key only if it does not exist, and PX gives the lock an expiry so a crashed holder cannot deadlock the system. The value should be a unique token so only the owner releases the lock.
token = str(uuid.uuid4())
if redis.set("lock:order:42", token, nx=True, px=10000):
try:
process_order(42)
finally:
redis.eval(
"if redis.call('get', KEYS[1]) == ARGV[1] then "
"return redis.call('del', KEYS[1]) else return 0 end",
1, "lock:order:42", token)
The Lua script makes check-and-delete atomic, preventing one client from deleting another's lock. For failover safety use Redlock across independent nodes, but note it is contested and cannot give strict fencing guarantees. Long tasks should renew the TTL and pass fencing tokens downstream.
10 How does Redis Cluster provide horizontal scaling? Hard
Redis Cluster shards data across nodes using 16384 hash slots. Each key maps to a slot via CRC16(key) mod 16384, and slots are assigned to masters. Clients may query any node; if the slot lives elsewhere the node replies with a MOVED redirection, and smart clients cache the slot map.
Each master has one or more replicas for failover. When a master fails, its replicas promote automatically once a majority of masters agree. Multi-key operations require all keys in the same slot, which hash tags can force: {user:42}:profile and {user:42}:sessions share a slot.
Limitations: only database 0 is available, some cross-key commands are unsupported, and the cluster needs at least three masters for a healthy quorum. Resharding moves slots between nodes online, enabling scaling without downtime.
Frequently Asked Questions About Redis Interviews
What do hiring managers evaluate in Redis technical rounds?
Technical interviewers look for foundational fluency, idiomatic syntax, clarity when communicating complex logic, and awareness of performance trade-offs (e.g. memory footprint, render performance, and network latency) in production environments.
What are the best interview tips for practicing Redis questions?
Use active recall: summarize each answer in your own words before revealing the model solution. Focus on explaining why a certain approach is chosen rather than just memorizing code syntax.