Real-Time Architecture: WebSockets, SSE, and Beyond
Not every real-time need requires WebSockets. Understanding the spectrum of real-time patterns helps you pick the right tool for each use case.
James Ross Jr.
Strategic Systems Architect & Enterprise Software Developer
Real-Time Is a Spectrum
"Real-time" in web applications covers a wide range of requirements. A stock ticker needs sub-second updates. A chat application needs messages delivered within a second or two. A dashboard that shows daily sales figures could refresh every 30 seconds and nobody would notice. A notification badge could update every few minutes.
Each of these has different infrastructure costs, complexity costs, and reliability requirements. Treating them all the same — reaching for WebSockets by default — leads to over-engineered solutions for simple problems and under-engineered solutions for complex ones.
The right approach is understanding the spectrum of real-time communication patterns and matching each use case to the simplest pattern that meets its requirements.
The Patterns
Polling is the simplest real-time pattern. The client makes periodic HTTP requests to check for updates. Every 5 seconds, the dashboard calls GET /api/stats and re-renders with whatever comes back.
Polling gets a bad reputation but it is genuinely appropriate for many use cases. If the data changes infrequently (every few minutes), if the number of clients is moderate, and if a few seconds of staleness is acceptable, polling is simple, reliable, and uses standard HTTP infrastructure. No special servers, no connection state management, no reconnection logic. The client is a regular HTTP client. The server is a regular HTTP server.
The downsides are latency (the client only sees updates on the next poll cycle) and wasted requests (most poll responses return "nothing changed"). Long polling partially addresses the waste: the server holds the request open until there is new data or a timeout expires, then responds. This reduces wasted requests but ties up server connections.
Server-Sent Events (SSE) provides server-to-client streaming over a standard HTTP connection. The client opens a connection, and the server pushes events to the client as they occur. The connection stays open. The client receives events in real-time without polling.
SSE is ideal when the communication is primarily one-directional: the server has data to push to the client, but the client does not need to send data back over the same channel (regular HTTP requests handle client-to-server communication). Live feeds, notification streams, progress updates, and dashboards are natural SSE use cases.
SSE has several practical advantages: it uses standard HTTP, works through proxies and load balancers without special configuration, supports automatic reconnection with the Last-Event-ID header, and is natively supported in all modern browsers through the EventSource API. For unidirectional server-to-client streaming, SSE is almost always the right choice over WebSockets.
WebSockets provide full-duplex bidirectional communication. Both the client and server can send messages at any time over a persistent connection. This is necessary when the client needs to send frequent messages to the server — chat applications, collaborative editors, multiplayer games, interactive tools where both sides are actively communicating.
WebSockets require more infrastructure: connection state management, heartbeats to detect dead connections, reconnection logic with state recovery, and load balancer configuration that supports persistent connections. They do not automatically reconnect on failure. They require explicit protocol design for the messages flowing in both directions.
Choosing the Right Pattern
The decision tree is straightforward:
Does the server need to push data to the client, or does the client also need to push data to the server?
If the communication is primarily server-to-client, SSE is the right choice. It is simpler than WebSockets, works with standard HTTP infrastructure, and handles automatic reconnection. Use SSE for dashboards, notification feeds, live updates, and progress indicators.
If the communication is genuinely bidirectional and frequent — both sides sending messages multiple times per second — WebSockets are necessary. Use WebSockets for chat, collaborative editing, real-time gaming, and interactive applications where the client and server are in constant dialogue.
If the data changes infrequently and a few seconds of latency is acceptable, polling is the simplest option. Use polling for periodic status checks, daily dashboards, and any use case where the data is not time-critical.
Many applications use multiple patterns simultaneously. The main dashboard uses SSE for live metric updates. The chat widget uses WebSockets for bidirectional messaging. The settings page uses standard request-response because nothing there needs real-time updates. Mixing patterns based on actual requirements is pragmatic engineering.
Infrastructure Considerations
Real-time connections — whether SSE or WebSocket — are persistent. This changes capacity planning compared to traditional request-response APIs.
A standard HTTP API handles a request in milliseconds and frees the connection. A server handling 1,000 requests per second might only have a few dozen connections open at any time. An SSE or WebSocket server with 10,000 connected users has 10,000 open connections simultaneously. Memory per connection, file descriptor limits, and connection management overhead become the scaling constraints.
Horizontal scaling requires sticky sessions or a pub/sub backbone. If User A is connected to Server 1 and User B is connected to Server 2, a message from A to B requires Server 1 to publish the message to a shared channel (Redis, a message broker) and Server 2 to deliver it to B. This fan-out infrastructure is where the real complexity lives in scaled real-time systems.
Edge computing platforms like Cloudflare Workers and Durable Objects are changing this landscape by moving WebSocket handling to the edge with built-in coordination. For applications where the client's geographic distribution matters, edge-based real-time infrastructure reduces latency while offloading connection management from origin servers.
If you are building a real-time feature and want to pick the right pattern and infrastructure for your specific requirements, let's talk.