Passa al contenuto principale

ADR-0018 - Live calls dashboard: SSE vs WebSocket

  • Status: Accepted (2026-05-21)
  • Deciders: Massimo Bagnoli, Claude
  • Implementation tasks: TASK-192, TASK-195
  • Supersedes: nessuno
  • Superseded by: nessuno

Context​

The NOC /live-calls dashboard needs a real-time stream of call.* events. The dashboard observes current call state; it does not need to send control messages back to the server.

Three transport options were considered:

  • Server-Sent Events.
  • WebSocket.
  • REST polling every 1-5 seconds.

Decision​

Use Server-Sent Events.

The backend exposes /api/v1/live/calls as a standard EventSource endpoint using sse-starlette. kam-cdr-bridge also publishes NATS events on call.events.<phase> as ephemeral pub/sub, separate from the durable cdr.raw JetStream path.

Redis keeps an active_calls sorted set used for initial snapshot population and reconnect resync.

Access is scoped by role:

  • Admin, operator and NOC users can observe all live calls.
  • Regular users are limited to their own company_id.

Rationale​

  • The stream is unidirectional from server to browser, which matches SSE.
  • SSE works over HTTP/1.1 through Caddy without WebSocket upgrade handling.
  • Browser EventSource provides built-in reconnect behavior.
  • SSE avoids WebSocket lifecycle concerns such as ping/pong and idle detection.
  • Polling adds request overhead and has 1-5 second latency instead of sub-second event delivery.

Consequences​

Positive​

  • The frontend can subscribe with the native browser EventSource API.
  • Caddy proxy configuration stays simpler than a WebSocket path.
  • Reconnect behavior is predictable and supported by browser defaults.

Negative​

  • SSE is server-to-client only; future bidirectional control actions would need a separate API or a new transport decision.
  • A large number of concurrent clients can create backpressure on the backend and NATS subscription path.

Limits​

The pilot target is 100+ concurrent SSE clients. GA scale-out and backpressure handling are deferred to a future task if production demand exceeds that target.

Alternatives considered​

WebSocket​

Rejected. Bidirectional transport is overkill for an observational NOC dashboard and adds connection lifecycle and Caddy upgrade complexity.

REST polling​

Rejected. It increases traffic and CPU with worse latency than event streaming.

References​

  • ADR-0016: CDR pipeline implementation and bridge event source.
  • TASK-192: backend SSE endpoint.
  • TASK-195: frontend EventSource subscriber.