DEV Community

Cover image for Say Goodbye to WebSockets? Why SSE Might Be Your New Best Friend

Say Goodbye to WebSockets? Why SSE Might Be Your New Best Friend

zakaria chahboun on February 11, 2025

Introduction Hey fellow devs! πŸ‘‹ Today, let's dive into Server-Sent Events (SSE) and explore why they might be your next favorite tool fo...
Collapse
 
miketalbot profile image
Mike Talbot ⭐

A warning: you're probably going to still need some kind of polling fallback. These days I check for receipt acknowledgement and then use the SSE stream for polling, which works, but the server has to close the connection if it doesn't get an "ack".

Collapse
 
zakariachahboun profile image
zakaria chahboun

Cool, thanks for sharing! I will read it. πŸ™

Collapse
 
kundan_kumar_7516aa7be04a profile image
KUNDAN KUMAR

True. I am still struggling to configure nginx properly for SSE

Collapse
 
miketalbot profile image
Mike Talbot ⭐
res.set({
        "Content-Type": "text/event-stream",
        "Cache-Control": "no-cache, no-store, must-revalidate",
        Pragma: "no-cache",
        Expires: "0",
        "Transfer-Encoding": "chunked",
        Connection: "keep-alive",
        "Access-Control-Allow-Origin": process.env.ORIGIN || request.get("origin") || "*",
        "X-Accel-Buffering": "no",
    })
Enter fullscreen mode Exit fullscreen mode

These are the headers I send

Collapse
 
rcls profile image
OssiDev • Edited

It's amazing that I've been at this for 15+ years and I'm still discovering new things like server-sent events. It was proposed 20 years ago already and somehow I've missed it completely. Simply never bumped into it.

Thanks for this post!

Collapse
 
zakariachahboun profile image
zakaria chahboun

Glad this post brought it to your attention! Do you think you'll use SSE in any of your projects?

Collapse
 
elanza48 profile image
Elanza-48

The title of the post is very misleading. You might get excited when you learn new things that doesn't mean "Saying goodbye to something", just for views don't do such nonsense.

Collapse
 
zakariachahboun profile image
zakaria chahboun

Not everything has to be taken so seriouslyβ€”sometimes a catchy title is just that. Take it easy!

Collapse
 
budgiewatts profile image
John Watts

Click bait is always click bait.

Collapse
 
octavio_santi_a4949b71ce5 profile image
Octavio Santi • Edited

I dont think this will replace the websockets, its just another technology for different use cases. SSE is for one way comunication and is more related to send notifications between the client and the server (for example in my job we have a react app who run inside of a 3rd party old electron app who has our app inside of an iframe and we needed to use SSE for sending an event to revoke all cookies in the electron application). If I need a chat or something "in real time" id still prefer to use web socket, things like push notifications SSE is the best choice

Collapse
 
zakariachahboun profile image
zakaria chahboun

Of course, it's not a replacement because they serve different purposes. But if you want to deal with real-time data, you should consider SSE first. If you need a more complex, duplex channel, then WebSockets are the way to go!

Collapse
 
rslhelper profile image
rslhelper

witching from WebSockets to SSE sounds like a big shift! SSE’s simplicity and lower overhead make it a strong alternative, especially for real-time updates. Curious to see how it holds up in high-demand applications!

Collapse
 
zakariachahboun profile image
zakaria chahboun

Try it and tell us πŸ˜‰

Collapse
 
5p4r70n profile image
jothish

It's just a brodcaster?
How the authorisation works here?
If there is 100 users , everyone will get everyones data??
I'm sorry I'm just a noob trying new things

Collapse
 
zakariachahboun profile image
zakaria chahboun

Great questions! SSE isn't just a broadcasterβ€”it's a way for the server to push updates to clients in real-time over a single HTTP connection.

As for authorization, it usually works by validating the user's identity before establishing the SSE connection, just like any other secure connection.

// Sends a GET request to /events
const eventSource = new EventSource('/events', {
    headers: {
        'Authorization': 'Bearer your_token_here'
    }
});

// Or Cookies
const eventSource = new EventSource('/events', {
    withCredentials: true // Ensures cookies and credentials are sent with the request
});
Enter fullscreen mode Exit fullscreen mode

The server responds with an HTTP response that has a Content-Type: text/event-stream header and keeps the connection open to send multiple events over time.

Regarding your last question: If you have 100 users, each client will only receive the data that the server sends to it. Typically, you would send specific updates based on the user’s permissions or the data they’re subscribed to, so not everyone gets everyone else's data.

Collapse
 
troy_high_e57325ac3b2b98c profile image
Troy High

@5p4r70n , you would have to use your existing auth model. For example, we use sse to send notifications to users of our system when they are in the admin console. The app uses tokens so the server only receives authenticated messages.

Also since we have info on the user via the token we store some identifier info on the cached connection pool so when a SSE is generated we can send only to clients that match the recipient id.

Collapse
 
peerreynders profile image
peerreynders

SSE is simplest described as a regular HTTP request with a streaming response; the streaming payload is events.

  • The server closing the response is unexpected, so the client sends another request to start again.
  • The client will close the connection when it is done with the request.

WS requests on the other hand convert (β€œupgrade”) the HTTP request to something outside of the HTTP spec to get access to the sockets that the original HTTP request was using.

In both cases the server has to manage a distinct connection to each user; however SSE connections tend to be less demanding on server resources and SSE may work where WS won't; like when firewalls block non-HTTP traffic. But both require an always-on server,so neither of them is suitable for a serverless environment.

Collapse
 
5p4r70n profile image
jothish

Ok, go it

The server and client will keep this connection alive for future server-to-client event notifications.

Thanks! 😊

Collapse
 
naveen_kumar_1949a763d392 profile image
Naveen Kumar

Few days back, we got a requirement where our DAO layer is collecting data from some files in the backend, as now this data can be large and we cannot load the complete data in memory hence we thought of going with SSE where server can send the data in chunks to Client in stream without loading the complete data.
In this case also SSE played a good role to send the data continuously without waiting to load in memory at once.

Websocket can be also used for this purpose but here we dont want duplex channel hence SSE played a vital role.

Collapse
 
zakariachahboun profile image
zakaria chahboun

Thanks for sharing your experience!

Collapse
 
andrewrhyand profile image
Andrew Rhyand

Using SSE as been a new pattern for me. After using tools like HTMX, I feel in love with sending back fragments of HTML.

Then I found Datastar data-star.dev/

It's a blend of JS signals, HTMX, and SSE.

Collapse
 
zakariachahboun profile image
zakaria chahboun

Have you used it in a real project? I mean "Data star"?

Collapse
 
andrewrhyand profile image
Andrew Rhyand

Internal tools only. It's still in beta with v1 on the horizon.

Collapse
 
dansasser profile image
Daniel T Sasser II

πŸ‘

Collapse
 
lovestaco profile image
Athreya aka Maneshwar

Pretty solid, btw how did you create the blog image?

Collapse
 
zakariachahboun profile image
zakaria chahboun

Thanks man! For the cover it's just AI generated.

Collapse
 
codesushil profile image
Code With Sushil

thanks man

Collapse
 
zakariachahboun profile image
zakaria chahboun

You're welcome man!

Collapse
 
albibelitung profile image
Albi Rental Belitung

thanks

Collapse
 
zakariachahboun profile image
zakaria chahboun

You are welcome!

Collapse
 
maysanders profile image
May Sanders

Server-Sent Events (SSE) can be a game-changer for real-time web applications, especially for use cases like notifications, live updates, and monitoring dashboards. Unlike WebSockets, SSE operates over a single HTTP connection and is inherently more efficient for unidirectional data streaming. However, when integrating SSE with GenAI applications, security risks must be carefully considered. Exposing AI-generated content through SSE could lead to data leakage, injection attacks, or unauthorized access if not properly secured. Implementing authentication, rate limiting, and content validation is essential to mitigate these risks.

Collapse
 
kalapee profile image
Kalapee Gajjar

Okay more seaport to back and

Collapse
 
ffreality profile image
Frozen Forest Reality Technologies

this requires http2, right ? SSE requires server-push which are available after http2

Collapse
 
zakariachahboun profile image
zakaria chahboun

Actually, SSE doesn't require HTTP/2. It's designed to work over HTTP/1.1 as well. Unlike HTTP/2's server push, which allows the server to proactively push resources to the client, SSE uses a single open connection over HTTP to stream events to the client. The key here is that SSE works through a long-lived connection, but doesn't require the features of HTTP/2 like multiplexing or server push.

Collapse
 
troy_high_e57325ac3b2b98c profile image
Troy High

@ffreality , SSE works with regular http, however, there is a connection limitation as @dylan_westraadt_92f0c807d mentioned. If using http/2 then the connection limit can be negotiated.

Collapse
 
mohitmajumdar profile image
Mohit Majumdar

can we get same SSE for python based backends???

Collapse
 
zakariachahboun profile image
zakaria chahboun

Yes, Just an HTTP GET request with specific headers 😊

Collapse
 
dylan_westraadt_92f0c807d profile image
Dylan Westraadt

SSE has a limit of 6 connections per browser window. Just something to keep in mind. Its not a one size fits all solution.

Collapse
 
peerreynders profile image
peerreynders

It's 6 connections (i.e. requests, not just SSE) per domain across the entire browser for HTTP/1.x. The limit is a lot higher for HTTP/2.

That said architecturally the plan would be to multiplex all traffic over a single SSE for the entire page and for an MPA to use leader election where only one page of the domain would use an SSE and redistribute the events to the other pages from the same domain via BroadcastChannel.

Collapse
 
zakariachahboun profile image
zakaria chahboun

Yes, But you can use one connection with multiple events.

Collapse
 
kundan_kumar_7516aa7be04a profile image
KUNDAN KUMAR

Hi
I tried SSE in my project. It worked great but I was not able to configure nginx properly for this.
If you have any suggestions please let me know.
Thanks in advance.

Collapse
 
zakariachahboun profile image
zakaria chahboun

SSE requires keeping the connection open for a longer time, so you need to make sure NGINX is configured to handle that.

Here are a few suggestions:

  1. Increase the buffer size and timeouts: SSE streams data continuously, so you need to adjust some NGINX settings. For instance, you might need to set a larger buffer and increase the timeout:
location /events {
    proxy_pass http://your_backend_server;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'keep-alive';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # Adjust timeouts for long-running connections
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;

    # Optional: Disable buffering for real-time data
    proxy_buffering off;
    client_max_body_size 0;
}
Enter fullscreen mode Exit fullscreen mode
  1. Keep the connection alive: Make sure the server and NGINX don’t timeout prematurely while the connection is open. The proxy_read_timeout and proxy_send_timeout parameters are key here.

  2. Turn off buffering: SSE requires that data be pushed to the client immediately, so turning off buffering in NGINX with proxy_buffering off is important for real-time delivery.

Whatch this video:
youtu.be/qoEq_Ro1wjU