Every pod relays the mailbox push, so the unread badge moves again

FixEmailService
Shipped
September 7, 2026 at 9:35 PM UTC
Author
Kamo
Commit
d6de046

The browser's email relay bound a DURABLE NATS consumer named after the member ("email-ws-<id>"). A durable push consumer admits exactly one subscriber, so with two replicas the second pod to bind was refused — [SUB-90012] Consumer is already bound to a subscription — and relayed nothing at all. It is in the deployed logs for four mailboxes today. Nothing about that looks broken from outside. The handshake is accepted, the STOMP session is healthy, /app/email/subscribe is honoured, and the opening unread snapshot is published to NATS exactly as it should be. It simply has nobody on that pod to carry it back, because convertAndSend's broker is in-heap: a frame only reaches a member if the pod holding their WebSocket relayed it, so every pod has to hear every message. The member gets a socket that never delivers a count, falls back to a one-shot REST read, and the mail badge then sits on that number until the page is reloaded — reading a message moves nothing. Which pod they landed on decided whether their badge worked, so it came and went and never looked like one bug. Ephemeral consumers carry no cross-pod identity, so there is nothing to collide over, and inactiveThreshold reaps one whose pod disappeared. This is what **************** exists for and what MediaService's relays already use; this was the last relay still holding a durable. Nothing is lost by the change: the durable was DeliverPolicy.New, so it never replayed either. The orphaned email-ws-* consumers are inert — the stream is limits-retention — and are left to age out rather than purged by hand.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing