SECTION 0 — REALTIME IS A DISTRIBUTED SYSTEM IN DISGUISE
Realtime features fail in predictable ways:
-
reconnect storms
-
fanout overload
-
ordering bugs
-
duplicate delivery
-
memory blowups from slow clients
Senior fullstack means your UI and backend cooperate on correctness and backpressure.
SECTION 1 — REQUIREMENTS
-
Show realtime notifications in web UI.
-
Mark as read.
-
Support offline users.
-
Delivery should be “near realtime,” not necessarily exactly-once.
SECTION 2 — TRANSPORT CHOICE: SSE VS WEBSOCKET
SSE
-
server → client only
-
simpler infra
-
works well behind proxies
WebSocket
-
bidirectional
-
supports richer protocols
-
more operational complexity
Senior default:
-
Use SSE if you only need server → client events.
-
Use WebSocket if you need client → server realtime interactions (chat typing, multiplayer, etc.).
SECTION 3 — EVENT MODEL + CONTRACT
Events should be versioned and typed:
-
notification.created -
notification.read
Envelope:
-
eventId(monotonic per user if possible) -
type -
payload -
occurredAt
Client contract:
-
client sends last seen
eventIdon connect -
server can replay missed events (bounded)
SECTION 4 — ARCHITECTURE
Producer services -> event bus/queue -> notification service
-> fanout to connections
-> store for offline
Data:
-
durable store for notifications
-
ephemeral connection registry (in-memory/redis)
SECTION 5 — BACKPRESSURE (THE SENIOR DIFFERENCE)
Slow clients are normal.
Mitigations:
-
per-connection send buffer limits
-
drop policy for non-critical events
-
disconnect slow consumers (with retry)
-
compress/batch events
Server rule:
Protect the system first; protect perfect delivery second.
SECTION 6 — ORDERING + DEDUPE
-
Provide ordering per user via
eventIdsequence. -
Client de-dupes by
eventId. -
Delivery is at-least-once; UI must be idempotent.
SECTION 7 — FRONTEND STATE
States:
-
CONNECTING
-
CONNECTED
-
DEGRADED (retry/backoff)
-
OFFLINE (explicit)
UX rules:
-
show last updated time
-
allow manual refresh
-
never block core navigation on realtime
SECTION 8 — FAILURE MODES
-
reconnect storm during deploy → exponential backoff + jitter
-
fanout overload → partition by userId, scale horizontally
-
missed events → replay endpoint:
GET /notifications?sinceEventId=... -
duplicate events → client de-dupe
SECTION 9 — OBSERVABILITY
-
active connections
-
events delivered/sec
-
buffer drops
-
reconnect rate
-
p95 event delivery latency
SECTION 10 — EXERCISES
-
Decide SSE vs WebSocket for your use case and justify.
-
Define your event envelope and versioning strategy.
-
Design your backpressure policy and what gets dropped.
-
Write the reconnect algorithm (backoff + jitter) for the UI.