Contents
For real-time features — chat, notifications, live order statuses — there are three approaches to choose from. WebSocket is for two-way communication with frequent messages, Server-Sent Events for data that flows only from server to client, and periodic polling for rare updates and the simplest cases.
Here is how these approaches differ, how to scale open connections and which mistakes are most common.
What are the ways to update data in real time?
There are three main ways: the client regularly asks the server (polling), the server keeps a stream open and sends events (SSE), or client and server keep a two-way channel (WebSocket). The choice depends on who initiates messages and how often they arrive.
| Approach | Direction | When it fits | Complexity |
|---|---|---|---|
| Polling | Client asks the server | Updates every tens of seconds, simple statuses | Low |
| Server-Sent Events | Server → client | Notifications, feeds, job progress, AI responses | Medium |
| WebSocket | Both ways | Chat, collaborative editing, games, trading | Higher |
When is ordinary polling enough?
Polling is enough when data changes rarely and a 10–30 second delay bothers nobody: application status, unread message count, payment state. It is the simplest option and works through the normal API, cache and load balancer with no changes.
The downsides show at scale: thousands of clients asking "anything new?" every few seconds create load even when nothing happens. We covered designing such endpoints in how to design a REST API.
How does SSE differ from WebSocket?
Server-Sent Events are a stream of events from the server over plain HTTP: the browser reconnects automatically and setup is simpler. WebSocket is a separate protocol with a two-way channel, needed when the client also sends data often and latency must be minimal.
// SSE: the browser reconnects automatically
const events = new EventSource('/api/orders/1842/stream')
events.addEventListener('status', (event) => {
const { status } = JSON.parse(event.data)
updateOrderStatus(status)
})
SSE is great for notifications, long-running job progress and streaming responses from language models. For chat or collaborative document editing, WebSocket is more convenient.
Photo: Unsplash
How do you scale connections?
Scale open connections with a dedicated real-time server, and pass messages between instances through a broker such as Redis. The main application publishes an event, and the real-time server delivers it to every subscribed client, whichever instance they are connected to.
What to plan for:
- A separate service for connections. Long-lived connections should not tie up the processes that serve ordinary requests.
- A message broker. Instances learn about each other's events through it — see Redis in a web project.
- Channels and authorisation. Users subscribe only to their own channels, and the server checks permissions on subscribe.
- Load balancer. It must support long-lived connections and proxy them correctly.
- Recovery after disconnects. The client reconnects and requests missed events by the last ID.
What are the most common mistakes?
The most common mistake is treating the real-time channel as reliable storage: a connection can drop at any moment, and a message sent at that moment is lost. The database must remain the source of truth, and the channel only a fast way to announce changes.
Typical mistakes:
- no data reload after reconnecting, so the user sees stale state;
- broadcasting to everyone instead of personal channels with permission checks;
- heavy logic inside the connection handler instead of a queue;
- no rate limits on client messages;
- WebSocket where polling every 30 seconds would do.
In short
- Polling suits rare updates, SSE a server-side stream, WebSocket two-way communication.
- SSE is simpler, runs over plain HTTP and reconnects by itself.
- A separate service holds connections; a broker passes events between instances.
- The real-time channel is delivery, not storage: reload data from the API after a reconnect.
- Do not overcomplicate: start with the simplest approach that solves the problem.
FAQ
Can you build real-time features with PHP?
Yes. Usually the PHP application publishes events and a separate server holds the connections — for example Laravel Reverb, Centrifugo or a hosted service. The business logic stays as usual.
How many connections can one server handle?
A specialised server on modern hardware can hold tens to hundreds of thousands of open connections. Message rate and fan-out logic usually become the limit before connection count does.
Do WebSockets work in mobile apps?
Yes, but only while the app is open. When it is in the background the OS closes the connection, so important events are duplicated as push notifications.



