Watermill Redis Message Queue Support: Deep Research Report
This post is a research report (originally published on zhichai.net) examining how the Watermill Go framework supports Redis as a message queue.
Key points
1. Redis Stream support (official, primary integration)
- Official support is provided through the standalone Go package watermill-redisstream, built on
redis/go-redis: - Repo: https://github.com/ThreeDotsLabs/watermill-redisstream
- Install:
go get github.com/ThreeDotsLabs/watermill-redisstream - Docs: https://watermill.io/pubsubs/redisstream/
- Redis Stream sits alongside Kafka, RabbitMQ, and NATS Jetstream in Watermill's officially supported Pub/Sub list.
- Message persistence: Unlike classic Redis Pub/Sub, Stream messages are appended to the stream with unique IDs and are not lost when consumers disconnect. RDB/AOF persistence and configurable stream length limits are supported.
- Consumer groups: Fully supported, enabling load balancing, failover (other instances take over unacked messages), horizontal scaling, and single-consumer processing per message.
- ACK mechanism: Subscriber receives message → application processes it →
msg.Ack()is called → the library sends XACK to Redis. Delivery semantics are at-least-once, so consumer logic should be idempotent. - Two distribution modes:
- *Fan-out*: no consumer group configured; uses
XREAD; every subscriber receives every message — suited to event notification. - *Load balancing*: consumer group configured; uses
XREADGROUP; messages are distributed among consumers — suited to task processing. - Publisher is created with
NewPublisherand aPublisherConfig, using a standard Redis client (redis.NewClient(&redis.Options{...})). - Native Redis Pub/Sub lacks persistence (messages are lost if no subscriber is connected).
- The report discusses Watermill's implementation strategy for Redis Pub/Sub and how it differs from the native mechanism, as well as its limitations.
- Redis List is not an officially supported Watermill Pub/Sub backend.
- The report explores the feasibility and approaches for a custom List-based implementation (e.g., using
LPUSH/BRPOP-style semantics), noting it would require building a custom Publisher/Subscriber against Watermill's interfaces. - https://watermill.io/pubsubs/redisstream/
- https://github.com/ThreeDotsLabs/watermill
- https://github.com/ThreeDotsLabs/watermill-redisstream
- https://pkg.go.dev/github.com/ThreeDotsLabs/watermill-redisstream/pkg/redisstream