SSE vs WebSockets vs polling
There are three common ways to get live data over HTTP, and they are not interchangeable. Here is how they actually differ, when each one wins, and why Hypeline's raw stream is Server-Sent Events.
Three transports, honestly compared
| Polling | SSE | WebSockets | |
|---|---|---|---|
| Direction | Client asks, repeatedly | Server pushes, one way | Both ways, full duplex |
| Transport | Plain HTTP requests | One long-lived plain HTTP response | Upgraded ws/wss connection |
| Freshness | As fresh as your interval | As events happen | As events happen |
| Reconnect & catch-up | Trivial (each poll is fresh) | Built in: reconnect and resume from a cursor | Yours to build: reconnects and gap-filling |
| Works through proxies & firewalls | Everywhere | Nearly everywhere (it is just HTTP) | Usually, but upgrades can be blocked |
| Client code | A loop and a timer | curl -N or EventSource, a few lines | A socket library and a protocol of your own |
| Server cost | Wasted requests when nothing changed | One idle connection per client | One connection plus protocol state |
The short version
Poll when data changes rarely and one consumer checking occasionally is enough. Use SSE when a server should push events to consumers over plain HTTP: it needs no special client, survives proxies, and reconnects cleanly. Use WebSockets when the client genuinely needs to talk back on the same connection: games, collaborative editing, bidirectional protocols.
Hypeline sits on both sides of this table. As a consumer, it speaks WebSockets and SSE natively to ingest live sources, and polls feeds and pages politely with conditional requests. As a producer, it exposes one SSE stream, because delivering events is exactly the one-directional job SSE was designed for:
curl -N https://api.hypeline.io/v1/stream \
-H "Authorization: Bearer sk_live_..." \
-H "Accept: text/event-stream"
# disconnected? resume exactly where you left off:
curl -N "https://api.hypeline.io/v1/stream?cursor=c_8f2a91d4" \
-H "Authorization: Bearer sk_live_..." Because the stream runs over HTTP/2, browser clients are not capped by the old six-connections-per-domain limit, and because resume is cursor-based, a dropped connection is an inconvenience rather than a data loss.
Frequently asked questions
Why does Hypeline deliver its raw stream over SSE and not WebSockets?
Because event delivery is one-directional and SSE keeps everything plain HTTP: one curl opens the stream, cursors give exact resume after a disconnect, and HTTP/2 multiplexing avoids browser connection limits. A duplex socket adds complexity without adding capability for this job.
Does Hypeline use WebSockets at all?
Yes, on the ingest side. As a consumer of other services, Hypeline speaks WebSockets natively: point it at a ws or wss streaming source and frames are matched and normalized into the same event stream as everything else.
Is polling ever the right answer?
For rarely-changing data consumed by one client, a poll with conditional requests is simple and fine. It stops being fine when you multiply sources and consumers: most polls return nothing, and freshness is capped by your interval. That is the gap a push stream closes.
What happens to an SSE stream when my process restarts?
With Hypeline you reconnect with the cursor of the last event you processed and the stream resumes exactly there. Missed events are replayed in order; nothing is lost while you were away.
Be first to make the static web live
Add your email and we'll tell you the moment it goes live.
No spam. One email when it goes live.