“Should we move the queue to Streams? They are the proper way now.” A colleague, this week, about our Redis list queue. Wrong question. Streams are not a newer version of the same thing.
A list queue is a hand-off. LPUSH on one side, BRPOP on the other, and once a consumer takes the message, it is gone. Crash after the pop and the message died with you, unless you built the pending-list dance yourself. No history, no second reader. For “send this email eventually” it is honestly enough.
Streams are a log. XADD appends an entry and the entry stays. Consumer groups each keep their own position, so billing and analytics read the same events independently. Delivery is tracked: a consumer must XACK, unacknowledged entries sit in a pending list where you can find them and XCLAIM them from a dead consumer. And you can replay. Read the stream from the beginning after you fix a bug. This alone justifies the feature.
So the real question is whether your messages are commands or facts. A command wants to be executed once and forgotten. A queue. A fact wants to be recorded and interpreted, maybe by several readers, maybe again later. A log.
Two warnings from practice. Retention is your job: XADD with MAXLEN, or the stream eats your memory, Redis will not decide what to forget. And do not squint at Streams until they look like Kafka. No partitions, no replicated log across a cluster, everything lives in one Redis and its RAM. As a light log inside a system that already has Redis, very good. As the company event backbone, no.
We kept the list. The email job does not need history, and I did not want to explain XCLAIM to whoever is on call.