Lists
Redis lists are doubly-linked lists of strings — ideal for queues, recent-activity feeds, and lightweight job buffers when you do not need Kafka's durability guarantees.
Introduction
Redis lists are doubly-linked lists of strings — ideal for queues, recent-activity feeds, and lightweight job buffers when you do not need Kafka's durability guarantees.
LPUSH/RPOP gives stack behavior; LPUSH/BRPOP gives blocking consumer queues. Lists are not sets — duplicates are allowed and order matters.
Use lists when producers and consumers share one Redis instance and message loss on crash is acceptable or handled elsewhere.
Understanding the topic
Key concepts
- LPUSH/RPUSH add to head/tail — O(1).
- LPOP/RPOP remove from head/tail — O(1).
- BLPOP/BRPOP block until element available — simple worker pool.
- LRANGE — fetch slice; LTRIM — cap list size.
- Lists encode as listpack (Redis 7+) for memory efficiency.
- Not for deduplication — use sets instead.
flowchart LRProducer -->|LPUSH| ListList -->|BRPOP| Worker1List -->|BRPOP| Worker2
Step-by-step explanation
- List head/tail pointers maintained in redisObject.
- Push inserts node; pop removes and returns element.
- Blocking pop waits on event loop with timeout.
- LTRIM keeps only index range — useful for capped feeds.
- No ack — message gone once popped unless requeued manually.
Syntax reference
Common commands
- BRPOP timeout 0 = block forever.
- LTRIM — keep last N items for activity feed.
- LLEN O(1) — monitor queue depth.
LPUSH email:queue '{"to":"a@x.com"}'BRPOP email:queue 30LLEN email:queueLTRIM recent:actions 0 99
Informative example
Spring service enqueueing background jobs:
@Servicepublic class JobQueue {private final StringRedisTemplate redis;public JobQueue(StringRedisTemplate redis) {this.redis = redis;}public void enqueue(String jobJson) {redis.opsForList().leftPush("jobs:email", jobJson);}public String dequeueBlocking(Duration timeout) {ListOperations<String, String> ops = redis.opsForList();return ops.rightPop("jobs:email", timeout);}}
Run BRPOP in dedicated worker threads. On failure, push to dead-letter list.
Real-world use
Real-world use cases
- Email/SMS dispatch queue between API and workers.
- Recent actions feed — LPUSH + LTRIM 0 49.
- Cross-service task handoff in monolith phase.
- Log buffer before batch write to warehouse.
- Simple RPC reply queue (requestId lists).
Best practices
- Cap list size with LTRIM to prevent unbounded growth.
- Use separate lists per priority or job type.
- Monitor LLEN; alert on sustained growth.
- Prefer streams when you need consumer groups and replay.
- Serialize jobs as compact JSON.
- Handle poison messages with dead-letter list.
Common mistakes
- Using list as unique job set — duplicates processed twice.
- No LTRIM on activity feeds — memory blowup.
- BRPOP in HTTP thread — blocks request pool.
- Assuming at-least-once without visibility timeout.
Advanced interview questions
Q1BeginnerList vs set?
Q2BeginnerWhat is BRPOP?
Q3IntermediateHow implement queue with lists?
Q4IntermediateList vs Redis Stream?
Q5AdvancedReliable queue on lists?
Summary
Lists = ordered queues and capped feeds.