Updates that arrive
without the page being refreshed
A feature that needs to feel live, a chat, a notification, a dashboard number ticking up as it happens, either polls the server every few seconds and feels laggy, or holds a websocket connection open and pushes updates the moment they happen. We built the event protocol behind a closed social network's live reputation and activity feed on exactly this kind of real-time connection.
What it is
A websocket is a persistent, two-way connection between a client and a server, held open rather than opened and closed per request, letting the server push an update the instant it happens instead of waiting for the client to ask. This is the infrastructure behind live chat, real-time notifications, collaborative editing, live dashboards and anything else that should update without the user refreshing or the app polling on a timer.
When you need it (and when you do not)
It earns its cost when an update genuinely needs to feel instant: a chat message, a live bid, a presence indicator, a reputation score changing as events happen. The event protocol behind a closed premium social network we built runs live activity and reputation updates to members over exactly this kind of persistent connection, since a feed that only updated on refresh would undercut the product’s entire premise of feeling alive.
It is the wrong tool, or at least overkill, when an update every ten or thirty seconds is genuinely fine for the use case, an order status that changes a few times a day does not need a persistent connection, a periodic poll is less infrastructure for the same practical result. We recommend polling over websockets whenever it honestly covers the need, since websocket infrastructure has real ongoing operational cost that a simple poll does not.
How we build it
We start by confirming the feature actually needs push, not just low-latency pull, since this decision shapes everything after it. When websockets are the right call, the server is built with reconnect handling as a first-class concern rather than an edge case: mobile networks drop connections constantly, in elevators, on trains, switching between Wi-Fi and cellular, so the client retries with backoff and the server resyncs any state the client missed during the gap, rather than silently losing messages.
Backpressure matters more than it looks like it should: a burst of events, a popular chat room, a trending item’s live bid count, can produce updates faster than a slow client’s connection can consume them, and a server that does not account for this will either drop messages unpredictably or let a buffer grow until the process runs out of memory. We build explicit backpressure handling, batching or dropping intermediate updates in a controlled way when a client falls behind, rather than discovering the failure mode in production.
Scaling past one server instance needs a pub/sub layer, since a websocket connection lives on the specific server instance that accepted it; an event published by one instance needs to reach connections held by others through Redis or an equivalent message bus. We build this from the start for anything expected to outgrow a single server, since retrofitting pub/sub onto a system built assuming one instance is a much larger job than building it in from day one.
What to watch
Authentication needs to happen on the websocket connection itself, not just on an initial HTTP handshake that then leaves the long-lived connection unchecked; a connection that stays authenticated by a token that could have been revoked since the handshake is a real security gap we close explicitly. Load testing matters more here than for a typical REST API, since the failure mode of too many concurrent open connections looks different from too many sequential requests, and we test against a realistic concurrent connection count before launch, not just functional correctness. And a feature with no fallback for networks or clients that cannot sustain a websocket, some corporate networks and older infrastructure block them, needs a polling fallback so the feature degrades gracefully instead of failing outright for those users.
Price and timeline
| Option | Price | What it covers | Timeline |
|---|---|---|---|
| Single-server real-time feature | from $3,000 | Chat or notification feed, reconnect handling, auth | 3 to 4 weeks |
| Scaled real-time system | from $7,000 | Pub/sub backend, horizontal scaling, load testing | 5 to 6 weeks |
Running cost is the websocket server plus the pub/sub layer, typically $30 to $200 a month depending on concurrent connections.
Related
This pairs with GraphQL API when the same data needs both queries and live updates, and with push notifications infrastructure for updates that should reach a user even when they are not actively connected. See the development service page for our full build process. For real examples, see the closed premium social network’s event protocol and the end-to-end encrypted messenger with a zero-storage relay.
Building a feature that should feel live but currently just polls? Get in touch and we will tell you honestly if websockets are worth the added infrastructure.
FAQ
How much does a real-time feature cost?
From $3,000 for a focused feature, live chat or a notification feed, with reconnect handling and basic scaling, 3 to 6 weeks. A feature needing to scale across many server instances with a pub/sub backend runs $6,000 to $12,000.
Do we actually need websockets, or would polling work?
If the update genuinely needs to feel instant, a chat message, a live auction bid, a collaborative cursor, websockets are the right tool. If an update every ten or thirty seconds is genuinely fine, a simple polling interval is far less infrastructure to build and maintain, and we recommend it over websockets when it is honestly sufficient.
What happens when a user's connection drops?
It happens constantly on mobile networks, and we build reconnect logic as a core part of the feature, not an edge case: the client detects the drop, retries with backoff, and the server replays or resyncs any state the client missed, so a brief tunnel or elevator dead zone does not lose messages.
How does this scale past one server?
A websocket connection is held open on one specific server instance, so scaling to more than one instance needs a pub/sub layer, Redis or an equivalent, so an event published by one server reaches a connection held by another. We build this from the start for anything expected to grow past a single instance's capacity.
Who owns the infrastructure?
You. The websocket server, the pub/sub configuration and the client code are set up in your own infrastructure, with load test results and a runbook for monitoring connection counts handed over.