Real Time communication
Real-time communication enables systems to deliver updates as soon as information changes, rather than waiting for clients to ask for new data.
In traditional request/response architectures, a client initiates every interaction. If new information is needed, the client must send another request. Real-time systems invert this pattern by allowing servers to push updates whenever events occur.
Many applications need information immediately. Waiting for users to refresh a page or repeatedly poll an API introduces unnecessary latency, wasted network traffic, and a poorer user experience.
Common use cases include:
- Chat and messaging applications
- Live dashboards and monitoring systems
- Notifications and alerts
- Financial market feeds
- Collaborative editing tools
- Multiplayer games
- Live tracking and telemetry systems
The core idea is: instead of repeatedly requesting new information, clients subscribe to a stream of events, exchange messages continuously, or connect directly to another peer, and receive updates as they happen.
This article covers: SSE, WebSockets, WebRTC.
Decision Tree
- Server pushes updates and clients mainly consume them -> SSE
- Both sides need to exchange information continuously through the server -> WebSockets
- Communication happens directly between peers, especially for voice, video, or low-latency data transfer -> WebRTC
flowchart TD
A[Need Real-Time Communication] --> B{Does communication happen<br/>directly between peers rather<br/>than through your server?}
B -->|Yes| C{Building voice/video, or need<br/>low-latency peer-to-peer<br/>data transfer?}
C -->|Yes| WEBRTC[WebRTC]
B -->|No| D{Do clients need to send<br/>real-time messages back<br/>to the server?}
D -->|Yes| WS[WebSockets]
D -->|No| SSE[SSE]
Comparison.
| Aspect | WebSockets | Server-Sent Events (SSE) | WebRTC |
|---|---|---|---|
| Mental Model | Persistent conversation between client and server | Continuous stream of server-generated events | Direct peer-to-peer channel for media and data |
| Communication Direction | Bidirectional | Server → Client only | Bidirectional, directly between peers |
| Connection Type | Persistent full-duplex connection | Persistent HTTP response stream | Direct peer-to-peer connection, established with signaling assistance |
| Browser Support | Excellent in modern browsers | Excellent in modern browsers | Excellent in modern browsers |
| Complexity | Medium | Low | High |
| Scalability Considerations | Requires managing stateful bidirectional connections | Typically simpler infrastructure and scaling model | Scales well 1:1; group communication needs additional infrastructure (SFU/MCU) |
| Latency | Very low | Very low | Very low once a direct connection is established |
| Reconnection Behavior | Usually implemented by application or framework | Built-in automatic reconnection support | Requires handling ICE restarts and renegotiation |
| Typical Use Cases | Chat, collaboration, multiplayer systems, interactive applications | Notifications, dashboards, monitoring, live feeds, status updates | Video calls, voice calls, screen sharing, peer-to-peer file transfer |
| Strengths | Full-duplex communication, highly flexible, supports interactive workloads | Simple implementation, HTTP-friendly, automatic reconnection, efficient for broadcasts | Lowest latency for direct exchange, reduces server bandwidth, native media support |
| Weaknesses | More operational complexity and connection management | No native client-to-server real-time channel | Requires signaling, STUN/TURN infrastructure, and NAT traversal handling |
WebSockets
The web followed a simple model:
Browser → Request
Server → Response
This worked well for websites but became problematic for real-time applications.
Developers had to use techniques like Polling, Long Polling, Comet, and Hidden iframes to simulate real-time communication. These approaches were inefficient because browsers repeatedly asked, "Do you have new data yet?"
WebSockets became an official web standard in 2011 through RFC 6455 and introduced a persistent, full-duplex connection between client and server.
Instead of:
Client -> Request
Server -> Response
Connection Closed
WebSocket provides:
Client <=================> Server
Always Open
Either side can send data at any time.
WebSockets thinks in conversations
WebSocket is for opening a connection and keeping it open. Once a connection has been established, both sides can continuously exchange messages. Core assumption: The application benefits from a long-lived connection where updates should be delivered immediately.
Example
Client
const socket = new WebSocket(
"ws://localhost:8080"
);
socket.onmessage = (event) => {
console.log(event.data);
};
socket.send("hello");
Server (Node.js)
wss.on("connection", (socket) => {
socket.on("message", (msg) => {
socket.send(`received: ${msg}`);
});
});
Communication:
Client -> hello
Server -> received: hello
No new HTTP request is required.
Network compatibility note: Some restrictive corporate networks, proxies, firewalls, or legacy infrastructure can interfere with WebSocket connections. This is one reason some teams prefer SSE or fallback solutions in environments where connectivity is less predictable.
Pros and Cons
| Pros | Cons |
|---|---|
| True real-time communication | Stateful connections |
| Full duplex messaging | More difficult to scale |
| Low latency | No built-in durability |
| Efficient for frequent updates | Harder debugging and observability |
| Native browser support | Cannot leverage HTTP caching |
| Reduces polling overhead | Requires connection management |
| Excellent for interactive applications | Not ideal for CRUD APIs |
Server-Sent Events (SSE)
Server-Sent Events (SSE) were introduced as part of the HTML5 specification effort, with early browser implementations appearing around 2009–2011 and the standard later reaching W3C Recommendation status. Before SSE, web applications wanting real-time updates typically used:
- Polling
- Long Polling
- Hidden iframes
- Custom Hacks
A common pattern:
Browser
|
GET /notifications
|
No updates
|
Wait 5 seconds
|
GET /notifications
|
Repeat forever
This wasted:
- Network bandwidth
- Server resources
- Client resources
Developers needed a standardized way for servers to push updates to browsers. SSE introduced one-way real-time communication from server to client over standard HTTP.
Instead of constantly asking for updates, the browser opens a connection and the server sends updates whenever they occur.
SSE thinks in event streams
Core assumption: The client mostly listens.
Communication looks like:
Server
|
Events
|
Browser
not:
Browser <-> Server
SSE is fundamentally one-way.
Example
Server
app.get("/events", (req, res) => {
res.setHeader(
"Content-Type",
"text/event-stream"
);
setInterval(() => {
res.write(
`data: ${Date.now()}\n\n`
);
}, 1000);
});
Browser
const events =
new EventSource("/events");
events.onmessage = (event) => {
console.log(event.data);
};
Output:
1726151231
1726151232
1726151233
...
The browser receives updates automatically.
Pros and Cons
| Pros | Cons |
|---|---|
| Extremely simple API | One-way only |
| Native browser support | Not ideal for interactive apps |
| Automatic reconnection | Limited binary support |
| Uses standard HTTP | Browser-oriented design |
| Efficient for notifications | Connection limits may apply |
| Easy to debug | Less flexible than WebSockets |
| Excellent for streaming updates | Requires separate channel for client-to-server communication |
WebRTC
Before WebRTC, real-time voice and video in the browser required proprietary plugins like Flash, Skype's browser plugin, or similar. There was no native way for two browsers to establish a direct connection and exchange audio, video, or data without routing everything through a server.
Google open-sourced WebRTC in 2011, aiming to bring peer-to-peer voice, video, and data communication natively into the browser, without plugins.
WebRTC is now the default technology behind most browser-based video calling, voice calling, and screen-sharing products, and is also used for peer-to-peer data transfer and some multiplayer game architectures.
WebRTC thinks in peers
WebRTC is about connecting two peers directly, so media and data can flow between them without passing through an application server.
Core assumption: once two peers are connected, they exchange real-time media or data directly, with a server only needed to help establish that connection.
Example
Peer A
const peer = new RTCPeerConnection();
const channel = peer.createDataChannel("chat");
channel.onopen = () => {
channel.send("hello");
};
Peer B
peer.ondatachannel = (event) => {
event.channel.onmessage = (msg) => {
console.log(msg.data);
};
};
Communication:
Peer A -> hello
Peer B -> received directly, no server relay
Pros and Cons
| Pros | Cons |
|---|---|
| Lowest latency for direct peer communication | Significantly more complex to implement |
| Native audio, video, and data channel support | Requires a signaling mechanism, which WebRTC itself doesn't provide |
| Reduces server bandwidth costs by avoiding relay | NAT traversal often requires STUN/TURN servers |
| True peer-to-peer data exchange | Group communication needs additional infrastructure (SFU/MCU) |
| Configurable reliable or unreliable data channels | Harder to debug than client-server protocols |
| Excellent for real-time media applications | Connection setup involves multiple negotiation steps |
| Works directly in modern browsers without plugins | Behavior can be less predictable across restrictive networks |
A Note on Delivery Guarantees
Neither SSE nor WebSockets guarantee message delivery while a client is disconnected — messages sent during an outage or a reconnect window can simply be missed. Systems that require durable delivery, replay, or guaranteed-once semantics typically reach for messaging platforms such as Kafka, NATS, RabbitMQ, or Pulsar instead of (or alongside) a real-time transport layer.
Key Takeaways
- Choose SSE when you need simple, one-way updates from server to client like: dashboards, notifications, and live feeds.
- Choose WebSockets when both sides need to exchange information continuously through your server. Examples: Chat systems, collaborative applications, and multiplayer applications typically need this.
- Choose WebRTC when communication should happen directly between peers like voice calls, video calls, screen sharing, or low-latency peer-to-peer data transfer.
- Choose polling when updates are infrequent and simplicity or operational ease matters more than immediate delivery.
Top comments (0)