Backend Development 13 min read

When to Choose SSE, WebSocket, or Polling? A Hands‑On Guide

This tutorial compares server‑push techniques—polling, WebSocket, and Server‑Sent Events—detailing their mechanisms, advantages, and drawbacks, then walks through setting up a simple SSE demo with Node.js and plain HTML, helping developers pick the right solution for real‑time data scenarios.

macrozheng
macrozheng
macrozheng
When to Choose SSE, WebSocket, or Polling? A Hands‑On Guide

Introduction

In everyday development we often need the server to push data to the client, such as real‑time dashboards, unread messages, or chat functions. This article explains the use cases of Server‑Sent Events (SSE) and how to implement them.

Server‑to‑Client Push Solutions

Polling

WebSocket

SSE

Polling Overview

Polling is a pseudo‑push technique where the client repeatedly sends single‑request HTTP calls and the server responds, creating the illusion of push. It is the least efficient method.

Disadvantages of polling:

Continuous requests require a full HTTP handshake each time, wasting resources.

The client must keep handling requests from page load, which is unfriendly.

Browser limits concurrent connections (e.g., Chrome allows six per host), and long‑running polls occupy those slots.

Long polling intervals may delay data delivery.

WebSocket Overview

WebSocket is a full‑duplex protocol that allows bidirectional communication between client and server. It is powerful but introduces a new protocol (ws/wss) that may not be supported by all browsers.

Compared with SSE, WebSocket is heavier and more complex.

WebSocket browser compatibility:

SSE Overview

SSE is a one‑way communication protocol based on a long‑lasting HTTP connection. The server can push data to the client, but the client cannot send messages back through the same channel.

<code>Long connections are a persistent HTTP/1.1 technique that allows multiple requests/responses over a single TCP connection, reducing server load and improving performance.</code>

Advantages of SSE:

Lightweight protocol with lower client overhead.

Uses standard HTTP, so existing servers support it without extra configuration.

Built‑in reconnection support.

Customizable data types.

SSE browser compatibility:

WebSocket vs SSE

Polling

Polling is a fallback when both WebSocket and SSE are unavailable.

WebSocket and SSE

Both are common for server‑client communication. Neither is universally better; the choice depends on the business scenario.

Business Scenarios

SSE is ideal for one‑way push use cases such as real‑time dashboards or notification centers where the client does not need to send data back.

WebSocket is suited for bidirectional communication like chat applications.

SSE Core API

<code>var source = new EventSource(url);</code>

SSE Connection States

0 – CONNECTING: connection not yet established or disconnected.

1 – OPEN: connection established, ready to receive data.

2 – CLOSED: connection closed and will not reconnect.

SSE Events

open – triggered when the connection is opened.

message – triggered when data is received.

error – triggered on communication errors.

Data Format

<code>Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive</code>

Practical Demo

Front‑end (plain HTML) creates an EventSource, listens for

open

,

message

, and

error

events, and appends received messages to a list.

<code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
  &lt;meta charset="UTF-8"&gt;
  &lt;title&gt;SSE Demo&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;ul id="ul"&gt;&lt;/ul&gt;
  &lt;script&gt;
    function createLi(data){ let li=document.createElement("li"); li.innerHTML=String(data.message); return li; }
    if (window.EventSource){
      const source = new EventSource('http://localhost:8088/sse/');
      source.onopen = ()=&gt;{ console.log("Connection opened"); };
      source.onmessage = e=&gt;{ const li=createLi(JSON.parse(e.data)); document.getElementById("ul").appendChild(li); };
      source.onerror = ()=&gt;{ console.log("Connection error"); };
    } else { throw new Error("Browser does not support SSE"); }
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>

Back‑end (Node.js + Express) sets CORS headers, defines

/sse

endpoint that returns

text/event-stream

, and sends a JSON message with the current time every second.

<code>const express = require('express');
const app = express();
const port = 8088;

app.all("*",(req,res,next)=>{ /* CORS headers */ next(); });

app.get("/sse",(req,res)=>{
  res.set({
    'Content-Type':'text/event-stream',
    'Cache-Control':'no-cache',
    'Connection':'keep-alive'
  });
  setInterval(()=>{
    const data={message:`Current time is ${new Date().toLocaleTimeString()}`};
    res.write(`data: ${JSON.stringify(data)}\n\n`);
  },1000);
});

app.listen(port,()=>{ console.log(`Server running at http://localhost:${port}`); });
</code>

Running the two files starts a simple SSE demo that streams the server time to the browser.

Conclusion

SSE is lighter than WebSocket.

SSE works over HTTP/HTTPS.

WebSocket uses a separate ws/wss protocol.

Use SSE for one‑way server‑to‑client pushes.

Use WebSocket for bidirectional communication.

Both have good browser support, except IE does not support SSE.

Polling should be avoided unless absolutely necessary.

Author: 工边页字 – Source: juejin.cn/post/7325730345840066612
real-timeNode.jsWebSocketExpressServer PushpollingSSE
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.