interviewDeck

Your one-stop platform to prepare, practice and ace your interviews.

Loading your questions…

All Questions

Filters & tools

Redis Interview Questions and Answers

23 hand-picked Redis interview questions with detailed answers. Open the interactive version above to search, filter by difficulty, run code, bookmark questions and track your progress.

What is Redis and what is it used for?

Redis is an in-memory data store that can optionally persist to disk. Extremely fast (sub-millisecond latency) because data lives in RAM. Supports rich data structures beyond simple key-value.

Common use cases:

  • Caching — reduce database load.
  • Session storage — shared sessions across app instances.
  • Rate limiting — token bucket / sliding window counters.
  • Pub/Sub — real-time messaging between services.
  • Leaderboards — sorted sets for rankings.
  • Distributed locks — coordinate across services.
  • Job queues — simple task queues with lists.

Redis data structures and their use cases.

TypeCommandsUse case
StringSET, GET, INCRCache, counters, simple KV
HashHSET, HGET, HGETALLObjects (user profile fields)
ListLPUSH, RPOP, LRANGEQueues, recent items feed
SetSADD, SMEMBERS, SINTERUnique items, tags, followers
Sorted SetZADD, ZRANGE, ZRANKLeaderboards, priority queues
StreamXADD, XREAD, XGROUPEvent logs, message queues
SET user:42:name "Alice"
HSET user:42 email "a@b.com" age 30
ZADD leaderboard 9500 "player1" 8700 "player2"

How does TTL and key expiration work?

Set expiration with EXPIRE key seconds or SET key value EX 300 (5 minutes). Redis uses two strategies:

  • Passive — key is deleted when accessed after expiry.
  • Active — background task randomly samples keys and deletes expired ones.

TTL key returns remaining seconds. PERSIST key removes expiration.

SET session:abc123 "{userId:42}" EX 3600
TTL session:abc123  # returns seconds remaining

Cache-aside, read-through, and write-through patterns.

Cache-aside (lazy loading) — app checks cache first; on miss, reads DB, writes to cache. Most common. Risk: stale data if DB updated without cache invalidation.

Read-through — cache layer loads from DB on miss (app only talks to cache).

Write-through — write to cache and DB synchronously. Always consistent but slower writes.

Write-behind — write to cache immediately, async flush to DB. Fast but risk of data loss.

val = redis.get(key)
if val is None:
    val = db.query(key)
    redis.setex(key, 300, val)
return val

How does Redis Pub/Sub work?

Publishers send messages to a channel. Subscribers listen on channels and receive messages in real time. Fire-and-forget — if no subscriber is listening, the message is lost.

Pattern subscriptions: PSUBSCRIBE order.* matches order.created, order.shipped.

Limitations: no persistence, no acknowledgment, no consumer groups. For durable messaging, use Redis Streams or Kafka/RabbitMQ.

# subscriber
SUBSCRIBE notifications
# publisher
PUBLISH notifications "New order #123"

What are Redis Streams?

An append-only log data structure (like a lightweight Kafka topic). Supports:

  • Consumer groups — multiple consumers share work, track progress.
  • AcknowledgmentsXACK confirms processing.
  • Persistence — messages survive restarts (unlike Pub/Sub).
  • Range queries — read from any point by ID.

Use for: simple event processing, activity feeds, reliable lightweight queues.

XADD orders * product_id 42 qty 3
XREADGROUP GROUP processors consumer1 COUNT 10 STREAMS orders >

RDB vs AOF persistence.

RDB (snapshots) — periodic point-in-time snapshots of the dataset to disk. Fast recovery, compact files. Risk: lose data since last snapshot (minutes of writes).

AOF (Append Only File) — logs every write command. More durable (configurable fsync: every second or every write). Larger files, slower recovery. Auto-rewrites to compact.

Both — recommended for production. RDB for fast restarts, AOF for durability.

# redis.conf
save 900 1        # RDB: snapshot if 1 key changed in 900s
appendonly yes      # AOF enabled
appendfsync everysec

Eviction policies when Redis runs out of memory.

When maxmemory is reached, Redis evicts keys based on maxmemory-policy:

  • allkeys-lru — evict least recently used keys (any key). Good default for caching.
  • volatile-lru — evict LRU among keys with TTL set.
  • allkeys-lfu — evict least frequently used (Redis 4.0+).
  • noeviction — return errors on writes. Use when data must not be lost.
maxmemory 2gb
maxmemory-policy allkeys-lru

What is pipelining in Redis?

Send multiple commands without waiting for each response — batch them in one round trip. Dramatically reduces latency for bulk operations (10–100x faster than individual commands).

Not the same as transactions — pipelining doesn't guarantee atomicity. Just reduces network overhead.

pipe = redis.pipeline()
for key, val in data.items():
    pipe.set(key, val)
pipe.execute()  # single round trip

Redis transactions (MULTI/EXEC).

MULTI starts a transaction; commands are queued. EXEC runs all queued commands atomically. DISCARD aborts.

Important: no rollback — if a command fails during EXEC, others still execute. No isolation from other clients between MULTI and EXEC (use WATCH for optimistic locking).

WATCH key — if key changes before EXEC, transaction is aborted (optimistic concurrency control).

WATCH balance:42
val = GET balance:42
MULTI
DECRBY balance:42 100
INCRBY balance:99 100
EXEC  # fails if balance:42 changed since WATCH

Why use Lua scripts in Redis?

Lua scripts execute atomically on the server — no other command runs during execution. Use for:

  • Complex read-modify-write without race conditions.
  • Rate limiting (INCR + EXPIRE in one atomic script).
  • Conditional updates (update only if current value matches).

Scripts are cached by SHA — send with EVALSHA after first EVAL.

EVAL "local c = redis.call('INCR', KEYS[1]) if c == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]) end return c" 1 rate:user:42 60

How do you implement distributed locks with Redis?

Basic pattern: SET lock:resource unique_id NX EX 30 — set only if not exists, with expiry. Release with a Lua script that deletes only if the value matches (prevents deleting another client's lock).

Redlock (Salvatore Sanfilippo) — acquire lock on N independent Redis instances for higher safety. Controversial but widely used via libraries (Redisson, Redlock-py).

Always set TTL — locks must auto-expire if the holder crashes.

SET lock:order:123 uuid-abc NX EX 30
# release (Lua)
if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) end

Implementing rate limiting with Redis.

Common approaches:

  • Fixed windowINCR key:{minute} with TTL. Simple but allows 2× burst at window boundaries.
  • Sliding window — sorted set with timestamps; remove old entries, count remaining. Accurate but more memory.
  • Token bucket — Lua script tracks tokens and last refill time. Smooth rate limiting.

Return 429 when limit exceeded. Libraries: rate-limiter-flexible (Node), Bucket4j (Java).

ZADD rate:user:42 {now_ms} {now_ms}
ZREMRANGEBYSCORE rate:user:42 0 {now_ms - 60000}
ZCARD rate:user:42  # count in last 60s

How does Redis Cluster work?

Horizontal sharding across multiple nodes. Key space divided into 16,384 hash slots. Each node manages a subset of slots. CRC16(key) mod 16384 determines the slot.

Clients route directly to the correct node. If a key's slot isn't on the connected node, Redis returns a MOVED redirect. Supports automatic failover — replicas promote to master on failure.

Limitation: multi-key operations only work if all keys hash to the same slot (use hash tags: {user}:profile and {user}:orders).

SET {user:42}:profile "..."
SET {user:42}:orders "..."  # same slot due to {user:42}

What is Redis Sentinel?

Sentinel provides high availability for Redis without full clustering. It monitors master and replicas, performs automatic failover if the master is down, and notifies clients of the new master address.

Deploy at least 3 Sentinel instances for quorum. Clients connect via Sentinel to discover the current master.

Use Sentinel for HA with a single master; use Cluster for horizontal scaling.

Using Redis for session storage.

Store session data as a hash or JSON string with a TTL matching session timeout. All app instances read/write the same Redis — enabling stateless horizontal scaling without sticky sessions.

Spring Session, express-session (with connect-redis), and Django-redis provide drop-in integration.

SET session:sess_abc "{userId:42, role:'admin'}" EX 1800
EXPIRE session:sess_abc 1800  # refresh on each request

Redis vs Memcached.

RedisMemcached
Data typesStrings, hashes, lists, sets, sorted sets, streamsStrings only
PersistenceRDB + AOFNone (pure cache)
ReplicationMaster-replica, Sentinel, ClusterNone built-in
ThreadingSingle-threadedMulti-threaded
Best forCache + data structure server + messagingSimple, high-throughput caching

Using Redis with Spring Boot.

spring-boot-starter-data-redis provides:

  • RedisTemplate<K,V> — generic Redis operations.
  • StringRedisTemplate — string-focused operations.
  • @Cacheable / @CacheEvict — annotation-based caching with Redis backend.
  • @EnableRedisRepositories — Spring Data Redis repositories.

Configure via spring.data.redis.host, port, password.

@Cacheable(value = "users", key = "#id")
public User findById(Long id) {
  return userRepo.findById(id);
}

What is HyperLogLog in Redis?

A probabilistic data structure for counting unique items (cardinality) with fixed ~12KB memory regardless of set size. ~0.81% standard error.

Commands: PFADD visitors user123, PFCOUNT visitors. Merge with PFMERGE.

Use for: unique visitor counts, unique search queries, deduplication at scale where exact count isn't needed.

PFADD page:views:2024-01-15 user_42 user_99 user_42
PFCOUNT page:views:2024-01-15  # returns ~2 (unique)

Bloom filters in Redis (RedisBloom module).

A probabilistic structure that answers "is this item possibly in the set?" with no false negatives but possible false positives. Fixed memory footprint.

Use cases: check if a username exists before hitting DB, spam URL filtering, cache penetration prevention (don't query DB for keys that definitely don't exist).

Available via RedisBloom module (Redis Stack) or implement with Bitmaps.

BF.ADD usernames "alice"
BF.EXISTS usernames "alice"   # 1 (probably yes)
BF.EXISTS usernames "nobody"  # 0 (definitely no)

Cache invalidation strategies.

The hardest problem in computer science. Strategies:

  • TTL-based — let entries expire naturally. Simple but stale data window.
  • Write-invalidate — delete cache key on DB write. Next read repopulates.
  • Write-update — update cache on DB write. Risk of race conditions.
  • Event-driven — DB change events (CDC, triggers) invalidate related cache keys.

For related keys, use cache tagging or versioned keys (user:42:v3).

def update_user(id, data):
    db.update(id, data)
    redis.delete(f"user:{id}")  # invalidate

Redis security best practices.

  • Authentication — set requirepass or use ACLs (Redis 6+).
  • Network — bind to private IP; never expose port 6379 to the internet.
  • Disable dangerous commands — rename or disable FLUSHALL, CONFIG, DEBUG.
  • TLS — encrypt data in transit for compliance.
  • Principle of least privilege — ACL users with only needed commands.
ACL SETUSER appuser on >password ~cached:* +get +set +del -flushall

Key Redis metrics to monitor.

  • Memory usage — used_memory vs maxmemory. Alert before eviction kicks in.
  • Hit rate — keyspace_hits / (hits + misses). Below 80% = cache not effective.
  • Connected clients — sudden spikes may indicate connection leaks.
  • Ops/sec — commands processed per second.
  • Blocked clients — clients waiting on BLPOP or slow scripts.
  • Replication lag — replica offset behind master.

Tools: Redis INFO command, RedisInsight, Prometheus redis_exporter + Grafana.

INFO memory
INFO stats  # keyspace_hits, keyspace_misses