Realtime Communication
Purpose
Evaluate whether the product needs realtime push at all, choose the lightest transport that serves it (polling → SSE → WebSockets), and design connection auth, channel authorization, reconnection, and scaling.
When to Use
- For live updates: notifications, chat, presence, collaborative state, progress feeds.
- Not when periodic refetch serves the UX — evaluate first; realtime is operationally expensive.
Inputs
- Realtime use cases with direction (server→client only vs bidirectional), frequency, and staleness tolerance.
- Auth model (
backend-authentication, backend-authorization), deployment shape.
Discovery Questions
- What staleness is actually acceptable per feature (30s polling often passes)?
- Server-push only (SSE fits) or client→server messages too (WebSockets)?
- What may each user subscribe to — and what proves it (
ownership-authorization)?
- Multiple instances — how do events reach connections on other nodes?
Responsibilities
- Make the transport decision explicit: polling (simplest, often enough), SSE (server→push, HTTP-native, auto-reconnect), WebSockets (bidirectional, most infrastructure); managed providers vs self-hosted as a stack decision.
- Authenticate the connection at establishment (cookie/token at handshake) and re-verify on sensitive subscriptions; connections outlive tokens — define expiry behavior (disconnect or re-auth).
- Authorize per channel/room at subscribe time: channel names are claims ("order-123's channel") that must pass the same ownership/tenant checks as REST access to that resource.
- Design reconnection: client backoff, and missed-event recovery (event IDs + replay window, or refetch-on-reconnect) — a reconnect that silently loses events is a data bug.
- Scale across instances: pub/sub backplane (e.g. Redis) so events reach every node's connections; sticky sessions where the transport needs them.
- Keep realtime as a delivery channel, not the source of truth: state changes commit to the database first; events notify (
../../database/transactions ordering).
Required Workflow
- Record the fit decision per use case (polling/SSE/WebSockets), with staleness reasoning.
- Design handshake auth + token-expiry behavior.
- Design channel model + subscribe-time authorization (negative tests: cross-user/cross-tenant subscribe rejected).
- Design reconnection + missed-event recovery.
- Design multi-instance fan-out.
- Specify tests: unauthorized subscribe rejected, reconnect recovers missed events, events follow commits.
Decision Rules
- Choose the lightest transport that meets staleness needs; upgrading later is easier than operating WebSockets you didn't need.
- A channel subscription is an authorization decision — same rigor, same negative tests, as the resource itself.
- Emit events after commit; an event about a rolled-back change is a lie.
- Presence/typing may drop silently; domain events may not — classify each event type.
Rules
- No unauthenticated socket accepts subscriptions.
- Channel naming never encodes secrets; names are guessable, authorization is the gate.
- Realtime infrastructure additions are stack decisions (approval).
Anti-Patterns
- WebSockets for a dashboard that could poll every 30s.
- Auth at handshake only, then honoring any channel name sent later.
- Reconnects that resume "from now," silently dropping the gap.
- Emitting events inside a transaction that later rolls back.
- Single-node event emit that misses connections on other instances.
Validation Checklist
Definition of Done
A recorded realtime design — justified transport per use case, authenticated connections, ownership-checked subscriptions, reconnection with event recovery, and instance-spanning fan-out — with negative tests for unauthorized subscription.
Related Skills
backend-authentication, backend-authorization, ownership-authorization, queues (backplane overlap), backend-observability (connection metrics), nestjs-foundation (gateways), rest-api-design (fallback endpoints).
Related Knowledge
../../../knowledge/ (staleness tolerances, concurrency expectations).
Related References
../../../references/backend/realtime/ (channel model, when populated).
Context Loading Guidance
- Requires: use cases with staleness/direction, auth model, instance count.
- Does not require: client rendering details, broker internals.
- May load:
ownership-authorization (subscribe checks), queues.
- Stop when: transport decisions and the channel/auth/recovery design are recorded.
Token Efficiency Guidance
The use-case × transport table plus the channel-authorization rules carry the design; don't restate socket library APIs.
1---2name: realtime-communication3description: Use to decide whether realtime is needed and design it — SSE vs WebSockets vs polling, authentication on connect, room/channel authorization, reconnection with missed-event recovery, and multi-instance fan-out.4---56# Realtime Communication78## Purpose910Evaluate whether the product needs realtime push at all, choose the lightest transport that serves it (polling → SSE → WebSockets), and design connection auth, channel authorization, reconnection, and scaling.1112## When to Use1314- For live updates: notifications, chat, presence, collaborative state, progress feeds.15- **Not** when periodic refetch serves the UX — evaluate first; realtime is operationally expensive.1617## Inputs1819- Realtime use cases with direction (server→client only vs bidirectional), frequency, and staleness tolerance.20- Auth model (`backend-authentication`, `backend-authorization`), deployment shape.2122## Discovery Questions2324- What staleness is actually acceptable per feature (30s polling often passes)?25- Server-push only (SSE fits) or client→server messages too (WebSockets)?26- What may each user subscribe to — and what proves it (`ownership-authorization`)?27- Multiple instances — how do events reach connections on other nodes?2829## Responsibilities3031- Make the transport decision explicit: **polling** (simplest, often enough), **SSE** (server→push, HTTP-native, auto-reconnect), **WebSockets** (bidirectional, most infrastructure); managed providers vs self-hosted as a stack decision.32- Authenticate the connection at establishment (cookie/token at handshake) and re-verify on sensitive subscriptions; connections outlive tokens — define expiry behavior (disconnect or re-auth).33- Authorize **per channel/room at subscribe time**: channel names are claims ("order-123's channel") that must pass the same ownership/tenant checks as REST access to that resource.34- Design reconnection: client backoff, and **missed-event recovery** (event IDs + replay window, or refetch-on-reconnect) — a reconnect that silently loses events is a data bug.35- Scale across instances: pub/sub backplane (e.g. Redis) so events reach every node's connections; sticky sessions where the transport needs them.36- Keep realtime as a **delivery channel, not the source of truth**: state changes commit to the database first; events notify (`../../database/transactions` ordering).3738## Required Workflow39401. Record the fit decision per use case (polling/SSE/WebSockets), with staleness reasoning.412. Design handshake auth + token-expiry behavior.423. Design channel model + subscribe-time authorization (negative tests: cross-user/cross-tenant subscribe rejected).434. Design reconnection + missed-event recovery.445. Design multi-instance fan-out.456. Specify tests: unauthorized subscribe rejected, reconnect recovers missed events, events follow commits.4647## Decision Rules4849- Choose the lightest transport that meets staleness needs; upgrading later is easier than operating WebSockets you didn't need.50- A channel subscription is an authorization decision — same rigor, same negative tests, as the resource itself.51- Emit events after commit; an event about a rolled-back change is a lie.52- Presence/typing may drop silently; domain events may not — classify each event type.5354## Rules5556- No unauthenticated socket accepts subscriptions.57- Channel naming never encodes secrets; names are guessable, authorization is the gate.58- Realtime infrastructure additions are stack decisions (approval).5960## Anti-Patterns6162- WebSockets for a dashboard that could poll every 30s.63- Auth at handshake only, then honoring any channel name sent later.64- Reconnects that resume "from now," silently dropping the gap.65- Emitting events inside a transaction that later rolls back.66- Single-node event emit that misses connections on other instances.6768## Validation Checklist6970- [ ] Fit decision per use case recorded (lightest sufficient transport).71- [ ] Handshake auth + expiry behavior designed.72- [ ] Subscribe-time channel authorization + negative tests.73- [ ] Missed-event recovery designed.74- [ ] Multi-instance fan-out designed.75- [ ] Events ordered after commit.7677## Definition of Done7879A recorded realtime design — justified transport per use case, authenticated connections, ownership-checked subscriptions, reconnection with event recovery, and instance-spanning fan-out — with negative tests for unauthorized subscription.8081## Related Skills8283`backend-authentication`, `backend-authorization`, `ownership-authorization`, `queues` (backplane overlap), `backend-observability` (connection metrics), `nestjs-foundation` (gateways), `rest-api-design` (fallback endpoints).8485## Related Knowledge8687`../../../knowledge/` (staleness tolerances, concurrency expectations).8889## Related References9091`../../../references/backend/realtime/` (channel model, when populated).9293## Context Loading Guidance9495- **Requires:** use cases with staleness/direction, auth model, instance count.96- **Does not require:** client rendering details, broker internals.97- **May load:** `ownership-authorization` (subscribe checks), `queues`.98- **Stop when:** transport decisions and the channel/auth/recovery design are recorded.99100## Token Efficiency Guidance101102The use-case × transport table plus the channel-authorization rules carry the design; don't restate socket library APIs.