iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Pub/Sub

Redis Pub/Sub is fire-and-forget broadcast: subscribers receive messages published while they’re connected, no replay. Use it for transient signals; reach for Streams when you need persistence and acks.

PUBLISH, SUBSCRIBE, patterns

EXAMPLE
# 1) Subscribe (in one client)
SUBSCRIBE notifications
# Now in another client, publish:
PUBLISH notifications '{"type":"signup","user":42}'

# 2) Pattern subscribe — wildcards
PSUBSCRIBE chat.* events.user.*
# Then
PUBLISH chat.global 'hi'
PUBLISH events.user.login '{"id":42}'

# 3) Inspect
PUBSUB CHANNELS                  # active channels
PUBSUB CHANNELS chat.*
PUBSUB NUMSUB notifications
PUBSUB NUMPAT                    # # of pattern subscriptions

# 4) Sharded Pub/Sub (Cluster, since 7.0)
SSUBSCRIBE shard.feed
SPUBLISH shard.feed 'cluster-aware message'

# 5) Node — ioredis
import Redis from 'ioredis';
const sub = new Redis();
const pub = new Redis();

await sub.subscribe('orders', 'cancellations');
sub.on('message', (channel, payload) => {
    const evt = JSON.parse(payload);
    handle(channel, evt);
});

await pub.publish('orders', JSON.stringify({ id: 'o1', total: 9.99 }));

// Pattern subscribe
const psub = new Redis();
await psub.psubscribe('user:*:logged-in');
psub.on('pmessage', (pattern, channel, msg) => {
    const userId = channel.split(':')[1];
    onUserLogin(userId, JSON.parse(msg));
});

# 6) Python — redis-py asyncio
import asyncio, json
from redis.asyncio import Redis

async def consume():
    r = Redis()
    async with r.pubsub() as p:
        await p.subscribe('updates')
        async for msg in p.listen():
            if msg['type'] == 'message':
                handle(json.loads(msg['data']))

# 7) Caveats — read these before shipping
#   • Subscribers MUST be connected at publish time — no replay
#   • Connection is dedicated — SUBSCRIBE client cannot run other commands
#   • Use STREAMS for at-least-once delivery, consumer groups, replay
#   • Use Pub/Sub for: cache-invalidation broadcast, websocket fan-out, ephemeral signals

# 8) Cache invalidation pattern
# App-side: after writing the DB, publish the invalidated key.
# Other instances subscribe and DEL their local LRU.
PUBLISH cache.invalidate 'user:42'
PUBLISH cache.invalidate 'feed:global'

Why it matters

Pub/Sub is the wrong tool for “at-least-once delivery” — subscribers offline at publish time miss the message forever. Use Redis Streams instead when delivery matters; use Pub/Sub for broadcasts where loss is acceptable (cache invalidation, presence pings).

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# subscriber
SUBSCRIBE news
# publisher
PUBLISH news "breaking…"
Try it Yourself »

Exercise

Subscribe to a channel.

news

Discussion

Loading…