Imagine you’re watching a stock market dashboard. Prices keep changing every second, sometimes multiple times in a second.
Would you prefer hitting refresh constantly, or having updates flow to you automatically?
That’s exactly where Server-Sent Events (SSE) shine. SSE provides a simple, reliable way for a server to continuously push updates to a client over a single HTTP connection.
In this article, we’ll break down what SSE is, how it works, how it compares to alternatives like WebSockets, and where you’d actually use it in real-world systems.
If you’re enjoying this newsletter and want to get even more value, consider becoming a paid subscriber.
As a paid subscriber, you'll unlock all premium articles and gain full access to all premium resources on algomaster.io.
What are Server-Sent Events (SSE)?
The web was built on a simple idea: request and response. A client (your browser) asks for a resource, and the server sends it back. Once the server responds, the connection is closed.
This model works beautifully for static websites, but it starts to show its limits in the modern world where users expect instant updates.
Think about how we consume information today:
live sports scores updating every few seconds
breaking news alerts popping up without a refresh
or notifications arriving instantly in a web app
These aren’t “request, wait, and reload” scenarios. They’re real-time streams of data.
This is where Server-Sent Events (SSE) come in.
Instead of forcing the client to constantly poll the server with “Got anything new?” requests, SSE allows the server to keep the connection open and push updates automatically as soon as they happen.
SSE is intentionally one-way. The server talks, and the client listens. That makes it a perfect fit for use cases where updates flow primarily in one direction. It turns a traditional one-off request into a long-lived subscription where the server continually sends data to the client over a single HTTP connection.
How is this different from WebSockets?
While WebSockets give you a full-duplex channel (both client and server can send messages at any time), SSE focuses on server-to-client delivery only.
This narrower scope makes it lighter, simpler, and easier to scale in scenarios where bi-directional communication isn’t necessary.
How SSE Works
To really understand SSE, it helps to walk through the full flow—from the moment the client connects to how messages are delivered and consumed.
1. Client Initiates the Connection
It all starts with the client (most often a browser) making a normal HTTP GET request to an endpoint on your server.
The magic lies in the headers. By specifying Accept: text/event-stream
, the client signals, “I’m expecting a continuous stream of events, not just a single response.”
In JavaScript, this is as simple as:
const eventSource = new EventSource('/events');
The EventSource
API is built into most modern browsers, making it incredibly easy to open an SSE connection.
2. Server Keeps the Connection Open
In a traditional HTTP response, the server sends back data and then closes the connection. SSE works differently. After receiving the request, the server responds with headers like:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Then it keeps the connection open indefinitely. This long-lived connection becomes a dedicated channel over which the server can push updates at any time.
3. Server Streams Events
The server doesn’t send random text, it follows a specific event-stream format. Each event is a block of text, terminated by a double newline (\n\n
). Some common fields include:
data:
– the actual message payloadevent:
– the event name (optional, lets you categorize events)id:
– a unique identifier for the event (useful for reconnection and resuming)retry:
– how long the client should wait before trying to reconnect (in ms)
Example stream:
data: This is the first message.
data: Another update.
event: user_update
data: {"id": 123, "name": "Alice"}
id: 45
event: stock_price
data: {"symbol": "AAPL", "price": 201.32}
Notice how different events can carry different types of data, all over the same connection.
4. Client Processes Incoming Events
Once the stream is open, the browser listens for messages and exposes them through the EventSource
API. There are two main ways to handle them:
Default handler (
onmessage
) – catches any event without a specificevent:
field.Custom event listeners (
addEventListener
) – handle named events.
Example:
// Handle generic messages
eventSource.onmessage = function(event) {
console.log("Received:", event.data);
};
// Handle a specific type of event
eventSource.addEventListener('user_update', function(event) {
const userData = JSON.parse(event.data);
console.log("User updated:", userData);
});
Why Choose SSE Over WebSockets?
While WebSockets are incredibly versatile, SSE offers distinct advantages in scenarios where you primarily need to push data from the server to the client:
Simplicity: SSE is built on top of HTTP, making it simpler to implement and debug. No special protocols or handshakes are required beyond the initial HTTP request. Many existing HTTP tools and infrastructure (proxies, load balancers) work seamlessly with SSE.
Automatic Reconnection: A significant advantage of EventSource in browsers is its built-in automatic reconnection mechanism. If the connection drops due to network issues, the browser will automatically attempt to reconnect, saving you the hassle of implementing this logic yourself.
Less Overhead: For one-way communication, SSE generally has less overhead than WebSockets, as it doesn't require the WebSocket handshake or frame-based messaging.
Browser Support: SSE is widely supported by modern browsers.
Text-Based by Default: While WebSockets can handle binary data, SSE is designed for UTF-8 encoded text data, which is often sufficient for many real-time updates.
Real-World Use Cases
Server-Sent Events shine in situations where data needs to flow continuously from the server to the client, but the client doesn’t need to talk back over the same channel.
Here are some common scenarios where SSE is a natural fit:
1. Live Sports Scores and Stock Tickers
Think of a cricket scorecard or a stock market app. The numbers change constantly, sometimes multiple times per second. With SSE, the server can stream these updates directly to the browser, ensuring users always see the latest score or price without hitting refresh.
2. News Feeds and Social Media Notifications
When a breaking news story is published or a friend likes your photo, you want to know instantly. SSE allows servers to push these updates in real time so users feel the experience is alive and immediate.
3. Progress Updates for Long-Running Tasks
Some backend operations like processing large datasets, transcoding a video, or generating a report can take minutes to complete. Instead of forcing users to repeatedly check status, the server can stream incremental progress updates (e.g., “25% complete,” “50% complete”) to keep them informed.
4. Real-Time Analytics Dashboards
Dashboards are most useful when they reflect the current state of the system. SSE is ideal for pushing new data points, refreshing charts, and updating metrics the moment they’re available without unnecessary polling overhead.
5. Read-Only Broadcast Channels
In chat systems or messaging platforms, not every channel needs two-way interaction. For example, an announcements channel where only moderators post updates can be efficiently delivered via SSE, ensuring subscribers receive messages instantly without the complexity of WebSockets.
Challenges and Considerations
While SSE is powerful, it's not a silver bullet. Keep these points in mind:
Browser Connection Limits: Browsers typically limit the number of concurrent HTTP connections to a single domain (often around 6). If you have many SSE connections from one client to the same server, you might hit this limit.
No Binary Data: SSE is designed for text. If you need to send binary data in real-time, WebSockets are a better choice.
Uni-directional: Remember, SSE is one-way. If your application requires frequent client-to-server communication in real-time, WebSockets are more appropriate.
State Management: Managing the state of many open connections on the server can become complex in large-scale applications.
Proxy/Load Balancer Configuration: Ensure that your network infrastructure (proxies, load balancers) are configured to handle long-lived HTTP connections without timing them out prematurely.
Wrapping Up
Server-Sent Events may not get as much hype as WebSockets, but they are a powerful, simple, and reliable way to build real-time features into your system.
If your application needs a steady stream of information, whether it’s live feeds, notifications, analytics dashboards, or progress updates, SSE gives you a lightweight, reliable solution without the extra overhead of managing full-duplex connections.
Thank you for reading!
If you found it valuable, hit a like ❤️ and consider subscribing for more such content.
If you have any questions or suggestions, leave a comment.
P.S. If you’re enjoying this newsletter and want to get even more value, consider becoming a paid subscriber.
As a paid subscriber, you'll unlock all premium articles and gain full access to all premium courses on algomaster.io.
There are group discounts, gift options, and referral bonuses available.
Checkout my Youtube channel for more in-depth content.
Follow me on LinkedIn, X and Medium to stay updated.
Checkout my GitHub repositories for free interview preparation resources.
I hope you have a lovely day!
See you soon,
Ashish
Hi,
Thanks for amazing article on SSE.
I recently used SSE at my work it worked perfectly fine on on premise servers where network rules were less ..but in cloud environmnet it failed with timeout becoz infra team waa not allowing long lived connection.
Then ww had to switch back to websocket.
I was wondering if this SSE are ever used in production level and if yes then hoe infra team handles the restriction on timout out for all requests as 2 second.
Let me know your thoughts on this
How it's different from pub sub model?