In this post, I'll discuss the pros and cons of using WebSockets to implement GraphQL Subscriptions. I'll then propose why we should consider deprecating the WS implementation in favour of a much simpler to use API, namely EventSource. Would love to hear your opinion!
https://wundergraph.com/blog/deprecate_graphql_subscriptions_over_websockets
Another major benefit of WebSockets is that you can control the exact timing of RPCs and subscriptions without having to worry about race conditions when the server expects to receive actions in a specific order.
Also, SSEs add a lot of overhead because you need to authenticate each SSE channel independently (unlike with WebSockets where you only need authenticate a socket once at the beginning and then use it to subscribe to almost unlimited channels); so if you have many SSE EventSources, establishing them will waste a lot of resources since you need to pass the auth token (or session ID) to each EventSource that you open - In general, SSE authentication is tricky and forces you to rely on cookies which can be a problem in a lot of situations (e.g. on mobile if the front end is loaded the local file system as part of a WebView, your cookies will not be sent to the server due to cross-origin restrictions).
Moreover, the lack of control over the lifecycle of the SSE connection makes it difficult to coordinate recovery from network or server failure/restart; a common problem happens when your server crashes and then all the SSE event sources try to reconnect immediately at the same time and this DDoSes your server again, then the reboot and crash cycle repeats indefinitely... With WebSockets, you can control the reconnect algorithm to add exponential backoff, for example (it can be customized to your exact requirements).
Finally, the statefulness of WebSocket connections can be a huge advantage; you can store data pertaining to a single active client in-memory on the server-side which can be convenient for a lot of use cases (and efficient). For example, you can attach an auth token on the back end socket (in memory) and can use it to quickly check access rights for any channel without having to make an additional database call.
SSEs are not a practical abstraction IMO. It's sad that people don't realize how good the WebSocket standard is. It's good because it's simple; it's also what makes it so flexible. WebSockets cover more use cases.
Subscriptions as a concept have to support too many use cases (too generic) to be implemented with something as restrictive as SSEs.