A Gentle Guide to HTTP Polling, WebSocket's, SSE, and Streamable HTTP

Imagine you're building a chat app. You've got users who want to send messages, get replies instantly, and see who's typing. Sounds simple, right? But under the hood, making a real-time chat app is all about choosing the right communication strategy between your user's browser and your server.
Let’s explore five major ways to build a real-time chat app—from the oldest trick in the book to the most modern web-streaming approach.
1. HTTP Polling – The Curious Kid
Analogy: Think of a curious kid asking their parent every few seconds: "Did I get any new messages? Did I? Now? What about now?"
How it works:
The browser (chat client) sends a request to the server every few seconds like:
setInterval(() => {
fetch('/chat/messages')
.then(response => response.json())
.then(showMessages);
}, 5000); // every 5 seconds
Pros:
Super simple to implement.
Works with any browser or backend.
Cons:
Slow: users get messages late.
Wasteful: lots of empty checks.
Not really "real-time."
Use case: Okay for very basic chat apps or low traffic scenarios.
2. WebSocket – The Phone Call
Analogy: Like a phone call where both people can speak and listen at any time.
How it works:
Once the WebSocket connection is open, both client and server can send messages to each other freely:
const socket = new WebSocket('wss://chat.example.com');
socket.onmessage = (event) => {
showMessage(JSON.parse(event.data));
};
socket.send(JSON.stringify({ user: 'Alice', message: 'Hello!' }));
Pros:
Truly real-time and bi-directional.
Great for rich interactions like typing indicators, online presence, etc.
Cons:
Needs a separate WebSocket server.
Can be tricky with proxies/CDNs/firewalls.
Use case: Ideal for fully-featured chat apps (e.g., Slack, Discord).
3. SSE (Server-Sent Events) – The Magazine Subscription
Analogy: You subscribe to a magazine, and they send you new issues automatically.
How it works:
You open a one-way stream from server to browser:
const evtSource = new EventSource('/chat/stream');
evtSource.onmessage = (event) => {
showMessage(JSON.parse(event.data));
};
Pros:
Simple, uses regular HTTP.
Great for live updates from server.
Cons:
One-way only: client can't send messages back.
Less control over reconnection, resending, etc.
Use case: Notification systems or apps where the server is mostly sending.
4. HTTP + SSE – Postman & Magazine Combo
Analogy: You write and send letters via postman (HTTP POST), and receive a magazine subscription with new messages (SSE).
How it works:
Use
fetch()
to send messages.Use
EventSource
to receive messages.
// Send message
fetch('/chat/send', {
method: 'POST',
body: JSON.stringify({ user: 'Alice', message: 'Hello!' }),
headers: { 'Content-Type': 'application/json' }
});
// Receive messages
const evtSource = new EventSource('/chat/stream');
evtSource.onmessage = (event) => {
showMessage(JSON.parse(event.data));
};
Pros:
Simple real-time setup.
Uses standard HTTP.
Cons:
Two separate connections (one for send, one for receive).
SSE has limitations on error handling and resuming.
Use case: Lightweight chat apps or support chat tools.
5. Streamable HTTP – A Live Conversation
Analogy: You're on a voice call where you're listening to a story, and the other person reads it to you as they write it.
How it works:
Open a POST request from client to server.
Server keeps the connection open and streams events back over it.
You send and receive on the same pipe.
Example:
const stream = new ReadableStream({
start(controller) {
controller.enqueue(JSON.stringify({ user: 'Alice', message: 'Hello!' }));
controller.close();
}
});
fetch('/chat/stream', {
method: 'POST',
body: stream,
headers: { 'Content-Type': 'application/json' }
}).then(response => {
const reader = response.body.getReader();
reader.read().then(function processText({ done, value }) {
if (done) return;
showMessage(value);
return reader.read().then(processText);
});
});
Pros:
Single endpoint: stream in and out.
Works better with modern cloud infrastructure.
Easier scaling compared to WebSocket.
Cons:
Requires HTTP/2 or HTTP/3 for full potential.
Still evolving as a pattern.
Use case: Modern chat systems or AI-driven messaging (e.g., chat with AI bots).
Comparison Table
Pattern | Real-Time | Bi-Directional | Complexity | Best For |
HTTP Polling | ❌ | ❌ | ⭐ | Basic chat apps |
WebSocket | ✅ | ✅ | ⭐⭐⭐ | Rich, real-time interaction |
SSE | ✅ | ❌ | ⭐ | Server announcements |
HTTP + SSE | ✅ | Partial | ⭐⭐ | Lightweight two-way chat |
Streamable HTTP | ✅ | ✅ | ⭐⭐ | Modern apps, serverless-ready |
Subscribe to my newsletter
Read articles from Srujana Penugonda directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
