CodePark/ questions / Pub/Sub & Streams
START PRACTICINGPRACTICE
Backend question · Redis & caching › Pub/Sub & Streams

Why do Node Redis clients need a separate connection for subscribing to Pub/Sub channels?

const sub = redis.duplicate();
await sub.connect();
await sub.subscribe("cache:invalidate", (message) => {
  localCache.delete(message);
});
await redis.set("user:42", "...");

A connection that subscribes can no longer run normal commands, so you need a second connection for them. This is how the RESP2 protocol works. RESP2 is the older protocol that Redis clients use to talk to the server.

With RESP2, once a connection sends SUBSCRIBE, it enters subscriber mode. After that it can only run:

  • subscription commands such as SUBSCRIBE, UNSUBSCRIBE and PSUBSCRIBE
  • PING, RESET and QUIT

A normal GET or SET on that connection fails.

So you keep one connection for regular commands and a separate one only for subscriptions:

  • In node-redis, you create it with client.duplicate().
  • In ioredis, you create a second Redis instance and listen for message events.

RESP3, the newer protocol, lets one connection mix pushed messages and normal commands. But separate connections are still the common and simplest setup.

Also note: after a network failure, the subscriber connection must reconnect and subscribe again. Anything published in between is lost.

  • In RESP2, subscriber mode limits the connection to subscription commands.
  • Use a separate connection only for subscribing.
  • Create it with duplicate() in node-redis, or as a second ioredis instance.
  • RESP3 can mix both on one connection, but separate connections are common.
  • Subscribe again after a reconnect, because missed messages are gone.