Question
Long Polling vs SSE vs WebSockets vs Comet in JavaScript
Question
I have read several articles, but the ideas are still not completely clear to me.
Could someone explain these technologies in a simple and practical way?
- Long Polling
- Server-Sent Events (SSE)
- WebSockets
- Comet
One explanation I keep seeing is that the server keeps a connection open and pushes data to the client. How exactly is that connection kept open, and how does the client receive and use the pushed data? A small code example would help.
Also, which of these should I use for a real-time application? I often hear about WebSockets, especially with socket.io in Node.js, but why is that commonly mentioned instead of PHP?
Short Answer
By the end of this page, you will understand what Long Polling, Server-Sent Events (SSE), WebSockets, and Comet are, how they send data from server to browser, and when each approach makes sense. You will also see why the server can "keep a connection open," how the browser receives new data, and why Node.js is often mentioned in real-time discussions even though PHP can also be used in some setups.
Concept
Real-time web communication is about reducing the delay between when something happens on the server and when the browser learns about it.
In classic HTTP, the browser sends a request and the server sends a response. After that, the connection usually ends. This works well for normal web pages, but it is not ideal for things like:
- chat apps
- live notifications
- stock price updates
- multiplayer games
- dashboards
To make updates feel instant, several techniques were created.
Long Polling
With long polling, the client sends an HTTP request and the server waits before responding. If there is no new data yet, the server keeps that request open. As soon as new data is available, the server sends the response. Then the client immediately sends another request and waits again.
So it looks like a continuous connection, but it is really a repeated cycle of request -> wait -> response -> new request.
Server-Sent Events (SSE)
SSE is a browser feature built on top of normal HTTP. The client opens a connection to the server, and the server keeps sending text-based event messages over that same response stream.
Important detail:
- communication is one-way: server -> client
- great for notifications, feeds, progress updates
- simpler than WebSockets when the browser does not need to send lots of real-time messages back
WebSockets
WebSockets start with an HTTP request, then upgrade the connection to a special protocol designed for ongoing two-way communication.
After the upgrade:
- client and server can both send messages at any time
- the connection stays open until one side closes it
- lower overhead than repeated HTTP requests
Mental Model
Think of each technique like a different way to receive updates from a restaurant kitchen.
Long Polling
You ask, "Is my order ready?" The staff does not answer right away. They wait until it is ready, then tell you. As soon as you hear the answer, you ask again.
That means you are repeatedly asking, but each question may stay open for a while.
SSE
You sit near a speaker that only the kitchen uses. The kitchen announces updates whenever something changes:
- "Order started"
- "Order ready"
- "Pickup now"
You only listen. You do not talk back through that speaker.
WebSockets
You and the kitchen are on a live phone call. Either side can speak at any time.
That makes it perfect for back-and-forth communication.
Comet
Comet is like the older collection of tricks restaurants used before they had better communication systems. Long polling is one of those tricks.
Syntax and Examples
Long Polling Example
Client side JavaScript:
async function poll() {
try {
const response = await fetch('/poll');
const data = await response.json();
console.log('Received:', data);
document.getElementById('output').textContent = data.message;
} catch (error) {
console.error('Polling error:', error);
} finally {
poll(); // start waiting again
}
}
poll();
Server idea:
- wait until new data exists
- respond with JSON
- client immediately opens the next request
SSE Example
Client side JavaScript:
const source = new ();
source. = () {
.(, event.);
.(). = event.;
};
source. = () {
.(, error);
};
Step by Step Execution
Trace Example: Long Polling
Client code:
async function poll() {
const response = await fetch('/poll');
const data = await response.json();
console.log(data.message);
poll();
}
poll();
Server behavior:
- if no new message exists, keep the request open
- when a new message appears, return
{ "message": "New update" }
Step by step
poll()runs for the first time.- The browser sends
GET /poll. - The server receives the request.
- If no new event is ready, the server waits instead of responding immediately.
- A new event happens on the server.
- The server sends back JSON like:
{ "message": "New update" }
Real World Use Cases
Long Polling
Useful when:
- WebSockets are unavailable
- older environments need support
- update frequency is low or moderate
- implementation simplicity matters more than efficiency
Examples:
- job status updates
- simple notification systems
- admin dashboards with occasional changes
SSE
Useful when:
- the server mainly sends updates to the browser
- the client does not need constant two-way messaging
- you want simple browser support with HTTP semantics
Examples:
- live news feeds
- deployment logs
- progress bars for long-running tasks
- live monitoring dashboards
WebSockets
Useful when:
- both client and server must send frequent messages
- low latency matters
- you need persistent two-way communication
Examples:
- chat applications
- multiplayer games
- collaborative editors
- trading platforms
- live cursor or presence updates
Comet
Useful mostly as historical understanding.
Examples:
- older real-time web apps before modern browser APIs
- legacy systems still using long polling or streaming hacks
Real Codebase Usage
In real projects, developers rarely think only in terms of the protocol. They think in terms of message flow, fallbacks, server limits, and user experience.
Common patterns
Guard clauses for connection state
if (socket.readyState !== WebSocket.OPEN) {
return;
}
socket.send(JSON.stringify({ type: 'chat_message', text: 'Hello' }));
This avoids sending data before the connection is ready.
Parsing structured messages
Real apps usually send JSON, not raw strings.
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'notification') {
showNotification(message.text);
return;
}
if (message.type === 'chat_message') {
(message., message.);
}
};
Common Mistakes
1. Assuming all real-time techniques are the same
They are not.
- Long polling: repeated HTTP requests
- SSE: one-way server -> client stream
- WebSockets: two-way persistent connection
- Comet: older umbrella term
2. Using WebSockets when SSE is enough
Broken decision pattern:
// Using WebSockets for a simple one-way notification feed
If users only need live notifications from the server, SSE may be simpler.
3. Forgetting to reconnect
Connections can fail.
Broken example:
const source = new EventSource('/events');
// no handling for errors or app state changes
Better:
source.onerror = (error) => {
console.error('Connection issue', error);
};
4. Sending before the socket is open
Broken code:
const socket = new ();
socket.();
Comparisons
| Concept | Direction | Transport Style | Best For | Limitations |
|---|---|---|---|---|
| Long Polling | Mostly server -> client | Repeated HTTP requests that wait | Basic real-time updates, compatibility | More overhead, less efficient |
| SSE | Server -> client | Single long-lived HTTP response stream | Notifications, feeds, logs | One-way only |
| WebSockets | Two-way | Persistent upgraded socket connection | Chat, games, collaboration | More setup and infrastructure complexity |
| Comet | Usually server -> client | Older push techniques like long polling/streaming | Historical/legacy systems | Not a single standard API |
SSE vs WebSockets
Cheat Sheet
Quick definitions
- Long Polling: client sends request, server waits, responds when data is ready, client repeats.
- SSE: browser opens an
EventSource; server streams events over HTTP. - WebSockets: browser opens a
WebSocket; both sides send messages anytime. - Comet: older umbrella term for server-push techniques like long polling.
Client APIs
// Long polling
fetch('/poll')
// SSE
const source = new EventSource('/events');
// WebSocket
const socket = new WebSocket('ws://localhost:3000');
When to use what
- Use Long Polling for compatibility or simpler fallback behavior.
- Use SSE for one-way live updates.
- Use WebSockets for true two-way real-time communication.
- Know Comet mainly as historical terminology.
Key rules
- Long polling is not the same as a permanent socket.
- SSE is one-way.
- WebSockets are two-way.
- The browser needs JavaScript event handlers to use incoming data.
- Real-time systems should handle reconnects and errors.
FAQ
What is the difference between long polling and WebSockets?
Long polling uses repeated HTTP requests that stay open until data is ready. WebSockets use one persistent two-way connection.
Is SSE better than WebSockets?
Not generally. SSE is better when you only need server-to-client updates. WebSockets are better when both sides need to communicate in real time.
Is Comet the same as long polling?
Not exactly. Long polling is one Comet-style technique. Comet is a broader, older term for browser push workarounds.
How does the server keep a connection open?
It simply delays finishing the response, or in the case of WebSockets, keeps the upgraded connection alive for future messages.
Can PHP be used for WebSockets or real-time apps?
Yes, but usually not with the most traditional request-per-page PHP setup. Real-time PHP often uses specialized libraries or separate services.
Why is Node.js often used for real-time apps?
Because its event-driven model and ecosystem made it popular for handling many simultaneous connections efficiently.
Should I use WebSockets for notifications?
Only if you also need two-way communication. If the server just sends updates to the browser, SSE is often simpler.
Do I still need JavaScript on the client?
Yes. The browser receives events, but your JavaScript code must decide what to do with the data.
Mini Project
Description
Build a tiny live notification demo that shows the difference between one-way and two-way real-time communication. The project uses Server-Sent Events for server-to-client updates because it is a simple and practical way to stream live messages to a browser.
This demonstrates how a server can keep an HTTP response open and push new data as events happen.
Goal
Create a page that receives a new server message every few seconds and displays it live without refreshing the page.
Requirements
- Create a small Node.js server with an
/eventsendpoint that streams SSE messages. - Create an HTML page that connects using
EventSource. - Show each incoming message in a list on the page.
- Send a new message from the server every 3 seconds.
- Handle connection errors in the browser console.
Keep learning
Related questions
Converting HTML and CSS to PDF in PHP: Core Concepts, Limits, and Practical Approaches
Learn how HTML-to-PDF conversion works in PHP, why CSS support varies, and how to choose practical approaches for reliable PDF output.
How PHP foreach Actually Works with Arrays
Learn how PHP foreach works internally, including array copies, internal pointers, by-value vs by-reference behavior, and common pitfalls.
How to Check String Prefixes and Suffixes in PHP
Learn how to check whether a string starts or ends with specific text in PHP using simple functions and practical examples.