1178

Both WebSockets and Server-Sent Events are capable of pushing data to browsers. To me they seem to be competing technologies. What is the difference between them? When would you choose one over the other?

Subhanshuja
  • 390
  • 1
  • 3
  • 20
Mads Mobæk
  • 34,762
  • 20
  • 71
  • 78
  • 5
    Not sure how you see them as competing. One is synchronous and could/would be used for near real-time data xfer, whereas the other is asynchronous and would serve an entirely different purpose (effectively sending toast-like messages from a server-side app). – Brian Driscoll Mar 04 '11 at 15:12
  • 31
    One thing I really like about SSE is that it's easy to troubleshoot...just open a request to your SSE server using `curl`. Since it's just a text format over HTTP, it's easy to see what's going on. – Sam Aug 16 '12 at 21:09
  • 17
    @BrianDriscoll - asynchronous/synchronous - which is which? As far as I can understand both enable asynchronous transfers? – Dave Everitt Sep 26 '13 at 09:34
  • 6
    SSE doesn't work on IE, websockets does – Tyler Gillies Mar 27 '15 at 08:02
  • @SSE is trivially patched on IE with less then 50 LOC. This point is moot. – oligofren Aug 09 '19 at 07:50
  • @oligofren do you have a reference? – cellepo Nov 24 '19 at 01:57
  • 3
    @cellepo See MDN's page on [SSE](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). It lists several polyfills. Remy Sharp's is 186 lines, which you could trim down quite a bit to the essentials, but yeah, 50 lines were a bit under ... ;) – oligofren Nov 26 '19 at 08:33
  • [Here](http://www.youtube.com/watch?v=vhJz3HftuZU/%22Here%22) is a talk about the differences between web sockets and server sent events. Since Java EE 7 a [WebSocket](http://docs.oracle.com/javaee/7/tutorial/doc/websocket.htm) API is already part of the specification and it seems that server sent events will be released in the [next](https://java.net/downloads/javaee-spec/SSE-in-EE8.pdf) version of the enterprise edition. – Patrick Leitermann Jul 12 '14 at 07:17
  • 1
    SSE is unidirectional. Using SSE data can't be sent to server. So it only is used in scenarios where only need to get updated data from server if the requirement is only like this then SSE is preferred over WS. – Md. A. Apu Mar 10 '23 at 12:19

7 Answers7

1389

Websockets and SSE (Server Sent Events) are both capable of pushing data to browsers, however they are not competing technologies.

Websockets connections can both send data to the browser and receive data from the browser. A good example of an application that could use websockets is a chat application.

SSE connections can only push data to the browser. Online stock quotes, or twitters updating timeline or feed are good examples of an application that could benefit from SSE.

In practice since everything that can be done with SSE can also be done with Websockets, Websockets is getting a lot more attention and love, and many more browsers support Websockets than SSE.

However, it can be overkill for some types of application, and the backend could be easier to implement with a protocol such as SSE.

Furthermore SSE can be polyfilled into older browsers that do not support it natively using just JavaScript. Some implementations of SSE polyfills can be found on the Modernizr github page.

Gotchas:

  • SSE suffers from a limitation to the maximum number of open connections, which can be specially painful when opening various tabs as the limit is per browser and set to a very low number (6). The issue has been marked as "Won't fix" in Chrome and Firefox. This limit is per browser + domain, so that means that you can open 6 SSE connections across all of the tabs to www.example1.com and another 6 SSE connections to www.example2.com (thanks Phate).
  • Only WS can transmit both binary data and UTF-8, SSE is limited to UTF-8. (Thanks to Chado Nihi).
  • Some enterprise firewalls with packet inspection have trouble dealing with WebSockets (Sophos XG Firewall, WatchGuard, McAfee Web Gateway).

HTML5Rocks has some good information on SSE. From that page:

Server-Sent Events vs. WebSockets

Why would you choose Server-Sent Events over WebSockets? Good question.

One reason SSEs have been kept in the shadow is because later APIs like WebSockets provide a richer protocol to perform bi-directional, full-duplex communication. Having a two-way channel is more attractive for things like games, messaging apps, and for cases where you need near real-time updates in both directions. However, in some scenarios data doesn't need to be sent from the client. You simply need updates from some server action. A few examples would be friends' status updates, stock tickers, news feeds, or other automated data push mechanisms (e.g. updating a client-side Web SQL Database or IndexedDB object store). If you'll need to send data to a server, XMLHttpRequest is always a friend.

SSEs are sent over traditional HTTP. That means they do not require a special protocol or server implementation to get working. WebSockets on the other hand, require full-duplex connections and new Web Socket servers to handle the protocol. In addition, Server-Sent Events have a variety of features that WebSockets lack by design such as automatic reconnection, event IDs, and the ability to send arbitrary events.


TLDR summary:

Advantages of SSE over Websockets:

  • Transported over simple HTTP instead of a custom protocol
  • Can be poly-filled with javascript to "backport" SSE to browsers that do not support it yet.
  • Built in support for re-connection and event-id
  • Simpler protocol
  • No trouble with corporate firewalls doing packet inspection

Advantages of Websockets over SSE:

  • Real time, two directional communication.
  • Native support in more browsers

Ideal use cases of SSE:

  • Stock ticker streaming
  • twitter feed updating
  • Notifications to browser

SSE gotchas:

  • No binary support
  • Maximum open connections limit
Alex Recarey
  • 20,178
  • 4
  • 25
  • 22
  • 170
    Chat is perfectly doable with SSE – you can use regular POST to send messages to the server. WebSockets would be needed only if you're implementing chat a'la Google Wave. – Kornel Jul 18 '11 at 09:45
  • 184
    It's true that chat and other real time applications can be done with SSE. However, this requires POSTing replies "out of band", ie, this is not controlled by the SSE protocol, and does not seem like a good example for a basic explanation on the differences between SSE and Websockets. You can implement chat with basic HTTP polling the server every second and POSTing new replies. This does not mean it's the best / most elegant way of doing it. – Alex Recarey Jan 09 '13 at 02:45
  • 20
    I think that pomeL's solution is a great compromise for most cases, since JS can always "push" things to the server with an AJAX POST. From my experience, the main issue has generally been the need for JS to poll for new information, but SSE takes care of that. :D – Jacob Pritchett Mar 02 '13 at 14:45
  • 1
    @porneL I don't remember how chat worked on Google Wave. So, for what kind of chat specifically would WebSockets be needed? – ma11hew28 Oct 31 '13 at 21:03
  • 20
    @MattDiPasquale Wave sent every key individually as you typed it instead of complete message at once. 200 bytes of POST overhead for 1 keystroke would be wasteful compared to about 6 for WebSocket. – Kornel Nov 02 '13 at 14:15
  • should websockets or server-sent events be used for a blogging website like twitter? – Lucas Apr 12 '14 at 23:47
  • 1
    I suggest amazing Darren Cook's book about SSE (in comparisons with websockets) and drawbacks (latency 3G net issues, etc.): http://shop.oreilly.com/product/0636920030928.do and myself I'm testing successfully SSEs with my microproject: https://github.com/solyaris/pere – Giorgio Robino Nov 27 '14 at 12:11
  • 22
    It seems a little odd to say they are not competing technologies, and then proceed to describe that they can both be used to achieve similar solutions. I would say that makes them competing. – Alex Aug 18 '15 at 20:49
  • 3
    Perhaps it needs to be mentioned explicitly: both SSE & WS support UTF-8 encoded data, but WS can also transfer _binary_ data. – Nil Apr 16 '17 at 17:15
  • 1
    SSE though does have max open connections limitation, which makes it not so easy to use in real life: [Firefox](https://bugzilla.mozilla.org/show_bug.cgi?id=906896), [Chrome](https://bugs.chromium.org/p/chromium/issues/detail?id=275955) – user3707125 May 11 '17 at 18:53
  • @Alex Maximum open connections limit is not any issue with SSE over HTTP2. Here is the explanation https://stackoverflow.com/a/47443366/1948585 – user1948585 Feb 26 '18 at 15:52
  • 2
    According to [this blog](https://streamdata.io/blog/push-sse-vs-websockets/), it is impossible for server to detect whether SSE is still alive before sending a message. – Franklin Yu Apr 18 '18 at 01:40
  • @Alex Recarey could you please explain more of what you mean by “out of band” - thanks. – cellepo Nov 24 '19 at 02:10
  • 3
    The limit is per domain, not per browser. I can have up to 6 sse toward www.example.com and other 6 sse towards www.example2.com – Phate Mar 17 '20 at 19:15
  • A Websocket gotcha: Basic Auth doesn't work in Websockets when using Safari: https://bugs.webkit.org/show_bug.cgi?id=80362 – Nahuel Greco Jun 03 '20 at 17:11
  • 3
    If the server uses HTTP/2, then all requests, including SSE, can be multiplexed into one single TCP connection, which could save resources, compared to using a WebSocket which requires a dedicated TCP connection. – Emil Nov 09 '21 at 17:50
  • If I have multiple subdomains like `sitea.example.com`, `siteb.example.com`...`sitez.example.com` do those all count as separate domains for the purposes of my 6? ie. is it just the _domain_ or is it the whole _host_ part of the URL? – Ed Randall Nov 29 '22 at 16:40
  • This answer was written 12 years ago. Some points are still valid. Others are not. So I'd recommend reading [this](https://stackoverflow.com/a/75010024) as well. – at54321 Mar 10 '23 at 20:56
150

According to caniuse.com:

You can use a client-only polyfill to extend support of SSE to many other browsers. This is less likely with WebSockets. Some EventSource polyfills:

If you need to support all the browsers, consider using a library like web-socket-js, SignalR or socket.io which support multiple transports such as WebSockets, SSE, Forever Frame and AJAX long polling. These often require modifications to the server side as well.

Learn more about SSE from:

Learn more about WebSockets from:

Other differences:

  • WebSockets supports arbitrary binary data, SSE only uses UTF-8
at54321
  • 8,726
  • 26
  • 46
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • 3
    I would like to point out in 2016 > 95% of global users natively support WebSockets. All browsers and devices have supported WebSockets for over 4 years. Socket.IO will fallback to AJAX long polling and handle the complexities of emulating WebSockets for you if it's not supported, which makes support 100%. If you're using anything but WebSockets in 2016, you're using outdated technology. – Nick Steele Aug 19 '16 at 17:03
  • 15
    @NickSteele That's a bullshit hype statement. Relying on older standards is perfectly fine if they meet your use case and doesn't mean anything is outdated. It's just a different standard. Ex: XHR can still do lots of stuff the Fetch API cannot do, so it's not outdated. It's different. I've used WS in the past, but know from experience that one can hit snags in the form of noise enterprise firewalls that block requests when it doesn't understand WS. SSE is super-efficient for what it does, is trivially understandable and implementable and easy to debug. For our one-way dataflow, it's perfect. – oligofren Aug 09 '19 at 07:56
  • @oligofren No need to swear. If something is designed to replace the previous version, and it's industry accepted and better in every way, by definition, the old method is outdated. Just like the original iPhone is outdated, so is XHR. XHR came out before Firefox, Chrome, the first iPhone, before YouTube, Netflix, Facebook and even MySpace. When XHR came out Windows 98 was the best OS, AOL was the best provider, and JSON didn't even exist. WebSockets replaced XHR almost a decade ago. If you hit snags using WS the thing that caused the snag is also outdated. There is no excuse to lag that far. – Nick Steele Aug 12 '19 at 17:24
  • 11
    Replace BS with hyperbole then :-) WS is not a replacement for XHR/HTTP any more than drones are for delivery cars. It's different use cases. WS is not HTTP and have different sweet spots. You'd end up reimplementing HTTP (poorly) in user space if you'd try. Also, you are implying things which are not given facts: WS is simply a bidirectional protocol supporting server push. I've never seen any design docs mention it being developed as the replacement for anything. Source? Age in itself is not a factor. When given a choice, choose the simplest implementation checking all your requirements. – oligofren Aug 12 '19 at 21:54
  • 8
    It's just two years ago (2017) I was debugging heap dumps of Node JS processes where the Socket.io code was causing massive memory fragmentation in the IIS process, ending up talking directly with Azure's Node team. The total complexity is not for free. If you can get away with a simple 20 line script as your dependency on the server, while still being able to serve 100K clients, I'd go for it. I love WS for what it does, though, but look at what you need before choosing a solution. – oligofren Aug 12 '19 at 21:59
  • 1
    Meanwhile (2021): WebSockets 97%, SSE 96%. – flix Jan 27 '21 at 07:46
23

Websocket VS SSE


Web Sockets - It is a protocol which provides a full-duplex communication channel over a single TCP connection. For instance a two-way communication between the Server and Browser Since the protocol is more complicated, the server and the browser has to rely on library of websocket which is socket.io

Example - Online chat application.

SSE(Server-Sent Event) - In case of server sent event the communication is carried out from server to browser only and browser cannot send any data to the server. This kind of communication is mainly used when the need is only to show the updated data, then the server sends the message whenever the data gets updated. For instance a one-way communication between the Server to Browser. This protocol is less complicated, so no need to rely on the external library JAVASCRIPT itself provides the EventSource interface to receive the server sent messages.

Example - Online stock quotes or cricket score website.
Gaurav Tiwari
  • 761
  • 7
  • 9
23

In 2023 the situation is not quite as it used to be.

Years ago, when IE still had a significant market share, one downside of SSE was the total lack of native support by IE (whereas WebSockets was supported by IE 10+). Nowadays, according to caniuse.com, both technologies are supported almost equally well on the client side: 98.35% for WebSockets vs 98.03% for SSE (those stats are for global users).

Historically, one severe limitation of SSE, the 6-connections-per-domain limit (a problem when yourapp.com is opened in many browser tabs) is not an issue anymore with HTTP/2. All modern browsers support HTTP/2 (97.16% of global users) and on the server-side HTTP/2+ has also surpassed HTTP/1 the last couple of years.

Various things need to be considered when chosing between SSE and WebSockets:

  • SSE is generally simpler to implement and easier to test/debug (a simple curl could be used).
  • WebSockets support bidirectional (full-duplex) communication. That said, SSE could be used in conjunction with AJAX if bidirectional communication is needed. WebSockets are often said to be the simpler option in those cases, but I think such generalizations can be misleading, as it largely depends on the type of application, how it's designed and the technologies used.
  • SSE supports UTF-8 text messages only, whereas WebSockets can also transmit binary data.
  • We can use SSE on the client side with the built-in EventSource API. However, nowadays people often choose to use a library, such as the popular fetch-event-source, which is an SSE-compatible alternative to EventSource that provides additional features, such as custom headers, more advanced retry strategies, automatically closing the connection when browser is minimized, etc.
  • From a practical standpoint, I'd also recommend to research how well your application server supports each of those technologies. Note that some rely on additional modules and/or libraries. You might want to look at some examples and maybe build a quick PoC.
at54321
  • 8,726
  • 26
  • 46
  • Why is the 6 connection limit a problem on http/1? I don't see how it's different than just with normal requests. Won't that connection terminate once it's complete freeing it again? Why is it anymore of a problem than regular http calls? – COOKIE Jun 22 '23 at 18:45
  • 1
    @COOKIE normal requests are short - the browser sends a request and the server returns a response. If the browser suddenly needs to make 50 requests, it will simply queue them and (normally) they will soon be processed. However, with SSE you have a permanent dedicated connection (imagine a request with a "never-ending" response). If `abc.com` uses 1 SSE connection, but a user opens `abc.com` in 7+ browser tabs, with the old `HTTP/1` the user would have a problem. – at54321 Jun 22 '23 at 19:25
  • Thanks for the quick reply. I was too focused on openAI's use of SSE, where they stream text instead of sending it all at once. In this case, I believe they would be the same it terms of connection usage? I was not thinking about other applications of SSE like notifications. – COOKIE Jun 22 '23 at 20:24
  • Another downside of SSE comes with the `EventSource` interface. You can not set anything other than `url` and `withCredentials` flag. So if your use-case requires sending additional data you have stuff into the URL querystring or resort to third-party implementations like `fetch-event-source` You also do not have control over retry strategy. EventSource will keep retrying at a fixed interval (defined by server) – MayThrow Jul 26 '23 at 00:47
  • @rzr thanks for bringing that up. Indeed, there are some limitations to the built-in `EventSource` and a lot of people nowadays use [fetch-event-source](https://github.com/Azure/fetch-event-source) as a more-powerful alternative. That's important, so I updated my post. – at54321 Jul 26 '23 at 05:24
19

Opera, Chrome, Safari supports SSE, Chrome, Safari supports SSE inside of SharedWorker Firefox supports XMLHttpRequest readyState interactive, so we can make EventSource polyfil for Firefox

Yaffle
  • 299
  • 2
  • 4
10

One thing to note:
I have had issues with websockets and corporate firewalls. (Using HTTPS helps but not always.)

See https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software https://github.com/sockjs/sockjs-client/issues/94

I assume there aren't as many issues with Server-Sent Events. But I don't know.

That said, WebSockets are tons of fun. I have a little web game that uses websockets (via Socket.IO) (http://minibman.com)

Drew LeSueur
  • 19,185
  • 29
  • 89
  • 106
9

they are different in semantics.

websocket has a native semantic meaning of "bidirectional data stream".

while sse has a native semantic meaning of "publish-subscribe pattern" or "request-respond pattern, despite the response is a stream".

of course you can implement a layer of "pub-sub pattern" or "req-res pattern" over websocket by yourself.

Zim
  • 1,528
  • 1
  • 10
  • 6