Back to all blogs

Exploring Real-time Web Architecture

December 12, 2025

if you've ever tried to build an chat application or a live dashboard you've probably faced the thing called "Real time data"

building standard REST API's are very starightforward: The client asks (request) and the server answers (response) and the connecion over, But what happens when the data on the server changes after that connection is finished? Imagine a stock market app. You fetch the price of Google stock at 10:00AM. and by 10:01 that data is alread stale The server has new data, but it has no way to tell the client because the connection is over

For the longest time i always thought the solution to this problem was always "Just use WebSockets"

But after deep diving into system designs and really understanding how those big applications with millions of user scales. i've realised that WebSockets are often overkill and sometimes they are a scalling nightmare for the server. in this article, i wanna talk you through the three main ways to handle real-time updates:

  1. WebSockets
  2. Polling
  3. SSE (server-sent events)

1. The "Default" choice WebSocket

when we talk about real time, websockets are usually the first tool we reach for. and for good reason, they are truely great

How it works

Unlike HTTP, where you open and close connections constantly, a WebSocket creates a persistent, full-duplex connection.

  • The client sends an HTTP "Upgrade" request.
  • The server agrees, and the protocol switches to WebSocket.
  • The Connection Stays Open: Now, we have a two-way pipe. The client can shout down the pipe, and the server can shout back, anytime, instantly.

The Good

It is true real-time. There is almost zero latency overhead after the initial handshake. If you are building a multiplayer game or a high-frequency chat app where users are typing violently at each other, this bidirectional (duplex) flow is perfect.

The "Scaling" Nightmare

Here is the part we often ignore during tutorials but hits us hard in production: WebSockets are Stateful.

Imagine you have a server (Server A) and it has 10,000 active WebSocket connections.

  • Hardware Limits: That server has a physical limit on how many open TCP connections it can hold.
  • Sticky Sessions: Because the connection is persistent, those 10,000 users are "stuck" to Server A. If Server A crashes? All 10,000 users get disconnected instantly.
  • Horizontal Scaling: This is where it gets messy. If you add Server B to handle more traffic, Server B doesn't know about the users connected to Server A. If User 1 (on Server A) sends a message to User 2 (who happens to be on Server B), the message won't go through unless you implement a complex Pub/Sub mechanism (like Redis) to bridge the servers.

I think WebSockets are powerful, but they force you to manage "state" at the infrastructure level. You can't just auto-scale effortlessly like you do with REST APIs.


2. The "Naive" Choice: Polling

Polling often gets a bad rep. It feels inefficient. Ideally, we shouldn't have to pester the server to ask, "Any news?" But here is the plot twist: Polling is likely what you should be using for 80% of your apps.

Short Polling

Short Polling Diagram This is the simplest version. The client sets a timer (say, every 2 seconds) and sends a standard HTTP request:

Client: "Hey, any new data?"
Server: "Nope."

(2 seconds later)

Client: "How about now?"
Server: "Yes! Here is the new stock price."

It is Stateless. This solves the biggest problem we had with WebSockets. Because every request is a standalone HTTP call, a Load Balancer can distribute these requests across any number of servers:

  • Request 1 goes to Server A.
  • Request 2 goes to Server B.
  • Request 3 goes to Server C.

If Server A crashes, the client doesn't even notice; the load balancer just sends the next poll to Server B. It is incredibly robust and easy to scale.

The Downside: You are "bombarding" your server. If you have 10,000 users polling every second, that’s 10,000 requests per second (RPS), even if nothing has changed.

Long polling

This is the clever optimization.

  • The client sends a request: "Any new data?"
  • The Wait: The server doesn't answer immediately if there's no data. It holds the request open.
  • The server waits until data actually arrives (or a timeout occurs).
  • Then it responds and closes the connection.
  • The client immediately sends a new request.

This reduces the number of "empty" checks. It feels "real-time" because the moment data arrives, the hanging request is fulfilled. However, it still occupies a connection slot on the server while waiting.


3. Server-Sent Events (SSE)

I feel like SSE doesn't get enough discussions it deserves. It sits right between the complexity of WebSockets and the "chattiness" of Polling.

How It Works

The client opens a connection and says, "I want to listen for updates." The server keeps this connection open (like a WebSocket), but it is Uni-directional (Simplex).

Server -> Client: Yes. The server can push data whenever it wants.
Client -> Server: No. The client cannot send data back over this specific pipe.

When to use it?

Think about a news feed, a live cricket score, or a system log stream.

In these cases, the user (Client) isn't generating data; they are just consuming it. You don't need the complexity of a full bidirectional WebSocket. You just need the server to push updates when they happen.

SSE is native to the browser, handles reconnections automatically, and is lighter to implement than WebSockets for one-way data flow.


The Verdict: What Should You Choose?

When choosing between real-time communication tools, use WebSockets when you need fast, high-frequency bidirectional updates like in multiplayer games. If your data updates at predictable intervals such as stock prices short polling is the simplest and most scalable option. For sparse or unpredictable updates, like chat messages, long polling or WebSockets avoid wasting requests while still delivering instantly. And if you only need a one-way stream of live data, such as sports scores, SSE offers a lightweight, persistent server-to-client solution.


Final Thoughts

As developers, we often chase the "coolest" tech. We think, "It's almost 2026, why would I use Polling? That's so 2010."

But in reality, Statelessness is peak. The ability to add servers without worrying about sticky connections or connection pools is a luxury that Polling provides. Don't be afraid to bombard your server if it means your architecture stays simple and resilient.

Sometimes, the best way to stay updated is just to keep asking, "Are we there yet?"