What Is WebSocket? How Real-Time Communication Works

What is WebSocket?
WebSocket is a network protocol that lets a browser and a server keep one connection open and exchange messages in both directions at any time. Once the connection opens, either side can send data whenever it wants, so you no longer start a new request for every piece of information.
Think of the difference between sending letters and making a phone call. With HTTP, you write a letter, the other side writes back, and the envelope closes. With WebSocket, you place the call once, and both people can talk for as long as the line stays open.
This article focuses on that single term. We cover how it starts, what it does well, where it struggles, and when you do not need it at all. For neighboring topics, we add short links to our other guides. We wrote the headings as questions so that beginners and experienced developers can jump straight to what they need.
What is WebSocket and why is HTTP alone not enough?
Put simply, HTTP works as question and answer. First, the client sends a request. Then the server returns a response, and the conversation ends. The server cannot tell the client "something just happened" on its own, because the client has to ask first.
That model is perfect for opening a page, submitting a form, or loading a product list. However, it breaks down for live chat, instant notifications, or live scores. In those cases, you cannot know in advance when the data will change.
For years, developers filled this gap with polling, because it needed no new technology. The client asks every few seconds whether anything new exists. Most answers are "no," and every question is a full HTTP request.
As a result, you get wasted traffic and added delay. If you ask more often, latency drops but server load grows. If you ask less often, load drops but users wait. WebSocket exists to solve this dilemma: the server speaks the moment it has something to say.
How does a WebSocket start: what are the HTTP handshake and protocol upgrade?
A WebSocket connection begins as an ordinary HTTP request. The browser sends special headers that tell the server it wants to switch this connection to the WebSocket protocol. In short, this step is the handshake.
If the server agrees, it answers with the status code "101 Switching Protocols." After that response, the same TCP connection stops speaking HTTP and starts carrying WebSocket frames. Also, the IETF document RFC 6455 defines this flow in detail.
Conceptually, the flow goes like this:
- The browser wants to connect to an address that starts with ws or wss.
- A normal HTTP request goes out, carrying an upgrade request and a randomly generated key.
- The server derives a verification value from that key and returns the 101 response.
- The client checks the verification value and treats the connection as open.
- From then on, both sides send messages as frames.
Starting as HTTP is a real advantage. Existing ports, proxies, and infrastructure already recognize the beginning of the exchange, so WebSocket can pass through most networks. In addition, the verification value proves that the server really speaks WebSocket, so a random web server cannot accept the connection by accident.
What is WebSocket doing after the connection opens: how do messages flow?
When the handshake ends, data travels in frames. A frame is the smallest unit of WebSocket communication. For instance, a message can fit in a single frame, or it can split into pieces. That way, you can start sending a large message without waiting for all of it.
In practice, messages come in two types: text and binary. Text messages, for example, usually carry formats such as JSON. Binary messages suit audio, image chunks, or compressed data.
The protocol also defines three kinds of control frames:
- A ping frame checks whether the other side is still alive.
- A pong frame is the automatic reply to a ping.
- A close frame ends the connection politely and can carry a reason.
Ping and pong matter most for quiet connections. A proxy or firewall in the middle may silently drop a connection that shows no data for a long time. A regular ping, in contrast, prevents that.
Which message format and subprotocol should you choose for WebSocket?
First, WebSocket is only a transport channel. It does not say what goes inside a message, so you have to fill that gap. Most teams choose JSON text messages because they are easy to read and debug.
The protocol also lets both sides agree on a subprotocol name during the handshake. The client lists the names it supports. Then the server picks one. As a result, both sides know from the start which message language they will speak on this channel.
A few habits make message design easier:
- Put a type (for example, "order created") and a version number in every message.
- Keep the message body small and send only the fields that changed.
- Validate every message from the client against a schema on the server.
- Ignore unknown message types quietly, so older clients keep working with a newer server.
In practice, a strict message contract pays off the most when teams ship at different speeds.
What is WebSocket used for in real applications?
WebSocket shines where you do not know when information will arrive and where delay hurts the user experience. Above all, the common trait is a frequent, unpredictable flow of data from the server to the client.
Typical use cases include the following:
- Live chat and customer support windows, where a message must land instantly.
- Instant notifications, where a new order, approval, or alert reaches the user right away.
- Live scores and tracking screens, where everyone sees the same data the moment results change.
- Collaboration tools, where several people work on the same document or board.
- Dashboards, where stock, orders, or system status change without a refresh button.
- Multiplayer games and interactive live broadcasts.
Every example in this list involves two-way traffic or very frequent updates. If you fetch your data a few times per day, simpler options are probably enough, as we explain below.
What is the difference between WebSocket, HTTP polling, long polling, and SSE?
Four common approaches exist for real-time communication. Each one, however, strikes a different balance. Instead of asking which one is best, ask which one fits your job.
| Approach | Direction | Connection pattern | Strength | Weakness |
|---|---|---|---|---|
| HTTP polling | Client asks, server answers | New request for every check | Simplest setup | Empty answers, delay, wasted load |
| Long polling | Client asks, server answers when data exists | Request waits, then a new one starts | Low delay, works with older infrastructure | Constant reconnecting and pending requests |
| Server-Sent Events (SSE) | Server to client only | One long HTTP response | Simple, automatic reconnect | One direction, text only |
| WebSocket | Both directions | One persistent connection | Low delay, text and binary data | Harder to scale and manage |
The table leads to one conclusion: your direction and frequency needs decide the choice. If you need frequent two-way data, WebSocket stands out. If news only flows from the server, SSE is often enough.
When is Server-Sent Events a better fit than WebSocket?
Server-Sent Events is a one-way stream from the server to the client, and browsers use it through the EventSource interface. According to MDN, the browser tries to reconnect on its own when the connection drops. Also, that behavior comes ready-made.
Picture a stock ticker, a news feed, or a progress bar for a long task. In these cases, the client rarely sends data, so it mostly listens. Because SSE runs over plain HTTP, proxy and firewall compatibility is usually easy too.
That said, SSE has limits. It only flows from server to client, so client data needs a separate HTTP request. It also does not carry binary data. For two-way scenarios such as chat, shared editing, or games, WebSocket is the more natural choice.
In short, the first question is whether the client also talks often. If the answer is no, evaluate SSE first. If the answer is yes, the question of what is WebSocket becomes a real requirement for you.
Example scenario: how does a live order board work with WebSocket?
Imagine the kitchen screen of a small restaurant chain. This is an example scenario, not a real customer. Waiters enter orders on a tablet, and the kitchen screen must show each order instantly.
With polling, the screen asks the server every few seconds. If an order arrives right after a check, the kitchen waits for the next one. During a rush, however, that wait becomes noticeable.
With WebSocket, the kitchen screen opens one connection at startup and keeps it open. When a waiter sends an order, the server pushes a "new order" message to those connections at once. When the kitchen sends back "ready," the waiter's tablet shows it immediately.
The two-way flow is critical here, because news must also travel from the kitchen to the waiter. Also, the same channel carries both the order and the status change. Moreover, the server knows which screen is connected, so it can notice a dropped screen and alert the staff.
Even in this scenario, you would not push everything through WebSocket. Data that rarely changes, such as the menu list or an old order report, stays simpler over normal HTTP.
What problems appear when you scale WebSocket?
First, the biggest cost of WebSocket is that connections stay open for a long time. For example, with classic HTTP, the server handles a request and frees the resources right away. With WebSocket, every connected user holds memory and a connection slot on the server.
Therefore, you need to think about two separate loads: message rate and the number of concurrent connections. A system that sends few messages but holds many open connections consumes different resources.
Common difficulties include these:
- Connection state lives on one server, so it disappears when that server goes away.
- The server a user is connected to may differ from the server that produces the message.
- A slow client can inflate the message queue and strain server memory.
- During a deployment, all connections drop at once and every client tries to reconnect together.
Still, the last item deserves special attention. A wave of reconnects can overwhelm the server with its own users. For that reason, plan for scale from day one.
How do slow clients and backpressure affect a WebSocket server?
If the server produces messages quickly and the client consumes them slowly, the difference piles up in a queue. That is the backpressure problem. MDN notes that the browser WebSocket interface offers no backpressure control.
On the server side, ignoring this buildup lets memory fill up slowly. Even one stuck client can strain the whole process after a while. So you need to set a buffer limit for every connection.
You can apply these measures:
- Put an upper limit on each connection's pending message queue.
- When the limit is hit, drop old intermediate values, since only the latest value matters in streams like live scores.
- Close a connection that stays very slow and let the client reconnect.
- Merge frequent changes and send them less often.
In the end, business rules decide which messages you can drop and which must arrive. Clarifying that early, therefore, simplifies the design.
What do load balancers and message brokers do in a WebSocket architecture?
First, a load balancer spreads incoming connections across several servers. For WebSocket, make sure the balancer supports the upgrade request and long-lived connections. If its idle timeout is too short, connections drop unexpectedly. We covered the general idea in our load balancer guide.
Every layer in the middle of the network can also affect a connection. Reverse proxies, content delivery networks, and firewalls may not be tuned for long-lived connections. If you hit trouble, check the layers along the path first, not the application.
The second problem is communication between servers. How does a message from a user on server A reach a user on server B? In practice, the usual answer is a message broker.
Specifically, a broker provides a publish and subscribe pattern. Then each WebSocket server subscribes to the broker. When a message arrives, the broker fans it out to all relevant servers, and each server forwards it to its own connected clients.
This pattern is a small application of event-driven design. You can read the full concept in our event-driven architecture article. For planning which component holds which connection, our microservices architecture guide helps too.
What is WebSocket security: what is the difference between ws and wss?
First, the ws scheme is an unprotected WebSocket connection. The wss scheme is the one you protect with TLS, just like the relationship between http and https. Therefore, we recommend wss in every live environment.
On an unencrypted connection, someone in the middle can read or change messages. Some proxies also break unencrypted WebSocket traffic. An encrypted connection, instead, reduces these problems significantly.
You can check that your certificate is valid and its chain is complete with our SSL checker. Also, when a page loads over https, browsers usually block an unencrypted ws connection as well, because of the mixed content rule.
Remember that wss protects only the transport layer. Questions such as who may connect and which messages they may send need a separate application layer design.
Why does a WebSocket connection need an origin check?
When a browser starts a WebSocket handshake, it adds an Origin header that names the page the request came from. RFC 6455 says a server can read that header and reject origins it does not accept.
Why does this matter? Because WebSocket does not follow the browser's same-origin policy in the usual way, so a page on another site can try to connect to your server from the visitor's browser. If authentication rests only on a cookie, the visitor's session can be used without their knowledge. Therefore, we call this risk cross-site WebSocket hijacking.
Fortunately, the defense is simple:
- Keep an explicit list of the origins you allow.
- Then reject any handshake from an origin that is not on the list.
- If you use cookie sessions, ask for an extra verification value.
The Origin header is reliable for browsers, but a non-browser client can write anything into it. Therefore, it is not enough alone; think of it together with authentication.
How do you set up authentication for a WebSocket connection?
The browser WebSocket interface does not let you send custom headers, such as Authorization, during the handshake. This restriction shapes your authentication design, and MDN's documentation points to the same limit.
Common approaches include these:
- Rely on the session cookie of the same domain and back it with an origin check.
- First get a short-lived, single-use ticket through a normal HTTP call, then present that ticket when you connect.
- Authenticate in the first message after the connection opens, and close any connection that fails.
If you use tokens, avoid putting a long-lived key inside the address, because addresses can stay in logs and proxy records. We explained token structure and signature logic at a conceptual level in our JWT guide.
Authorization, however, is a separate step. Just because a connection is open, do not let it subscribe to every channel. On each subscription, ask the server again whether this user may see this channel.
How do you design reconnection when the connection drops?
First, real networks drop. A phone enters a tunnel, a user moves from Wi-Fi to mobile data, or a server restarts. Unlike SSE, the browser WebSocket interface does not reconnect by itself, so you have to write that logic.
A good reconnection design has a few parts:
- Increase the wait time after each attempt, which people call exponential backoff.
- Add a small random delay so that not every client returns at the same moment.
- Decide how you will recover missed messages after reconnecting, for example with the last seen message number.
- Finally, show the user the connection state honestly.
However, many teams skip the missed message problem. WebSocket does not promise delivery, so a message can vanish if the connection broke. For important data, keep a durable record on the server so the client can resume where it left off.
How do you monitor and measure WebSocket connections?
Open connections are invisible, so problems surface late. For that reason, monitoring matters even more for WebSocket systems than for an ordinary API. In practice, a few basic measurements reveal most issues early.
- Current open connection count: sudden drops suggest mass disconnects, and steady growth suggests a leak.
- Connects and disconnects per second, which catch reconnect waves.
- Close reasons, because a network drop is not the same as a server decision.
- Message latency, meaning the time between producing a message and its arrival at the client.
- Queue length per connection, because it exposes slow clients.
If you want to combine these measurements with logs, metrics, and traces, the approach in our observability article will help. You can also find the basics of network delay in our ping and latency guide.
Can you use WebSocket outside the browser?
Yes. RFC 6455 says the protocol was designed for scripts in web pages, but any client can speak it. Mobile apps, desktop programs, and server-to-server connections are examples.
For example, a mobile app can keep an open WebSocket connection so it can show an incoming message right away. A monitoring service can also listen to an event stream from another service this way. As a result, clients outside the browser use the same messaging model.
However, there is one difference. For non-browser clients, the Origin header is not a reliable identity, because the client can write whatever it likes. On the other hand, these clients can send custom headers, so you can build authentication on headers. So you should think about the threat model for each client type separately.
On mobile, network switches are frequent, so reconnection logic becomes even more important. Do not forget battery use either, because a constantly open connection may be unnecessary for an app that people use rarely.
How do channels and rooms route WebSocket messages?
First, the WebSocket protocol does not know who a message is for. Data you write to a connection goes only to that connection. Rules such as "send this order only to screens of that branch" are yours to build in the application layer.
For that, you use the idea of channels or rooms, which keeps the logic simple and easy to review. Each connection subscribes to the channels it cares about. A branch number, a chat room, or a document ID can be a channel name. When a message is written to a channel, the server delivers it only to that channel's subscribers.
This approach has three benefits:
- Users receive only the relevant data, so network load drops.
- You do the permission check in one place, at the start of the subscription.
- Combined with a message broker, the channel name becomes the key for distribution across servers.
Keeping channel names hard to guess, however, does not provide security on its own. So always run the permission check on the server.
How do you test a real-time feature?
A chat that works with a few tabs on your own machine may, however, behave differently in production. Therefore, bring your tests closer to real conditions. Asking only whether the message arrived is therefore not enough.
Add these scenarios to your plan:
- Cut the connection on purpose and verify that the client reconnects and receives the messages it missed.
- Connect many clients at once and watch the server's memory and processor behavior.
- Simulate a slow network and confirm that the queue limit works.
- Restart the server and check that all clients return gradually.
- Try to subscribe an unauthorized user to another channel.
First, run these experiments in a separate test environment before going live. Explaining what is WebSocket to your team is easy, but seeing its behavior takes tests. Also write down the results, because you will have concrete data for future scaling decisions.
When is WebSocket unnecessary?
Not every real-time-looking need, however, calls for WebSocket. Before you complicate your infrastructure, ask whether the data really must change within seconds, and whether users would notice.
Simpler solutions are often enough in these cases:
- If data changes once a minute or less, regular polling is enough.
- If the flow goes only from server to client, SSE can be lighter.
- If users already refresh the page often, an extra channel is pointless.
- For content that you can cache and that looks the same to everyone, classic HTTP is cheaper.
For caching logic, see our caching guide. In addition, holding long-lived connections can be hard on serverless platforms, so read our serverless article for details.
Put simply, simple is often more durable. A WebSocket without a clear reason only adds maintenance work.
What are the most common WebSocket mistakes?
The mistakes teams make most often are design errors, not technical ones. Knowing a few, therefore, gives you a good starting point.
- Sending everything through WebSocket. Login and file upload work more comfortably over normal HTTP.
- Skipping a schema and version in messages. When client and server move at different speeds, old messages lose their meaning.
- Not tracking the connection count. Open connections pile up quietly and hit a limit one day.
- Broadcasting every event to everyone. Send a user only the messages of the relevant channel.
- Not recording errors and close reasons. If you do not know why drops happen, you cannot improve.
- Trusting client input. Validate every incoming message on the server.
Teams that answer what is WebSocket only on the surface treat it as a magic speed button, and that is the shared root of these mistakes. In reality, connection management, security, and scaling stay your responsibility.
What is WebSocket planning like as a checklist?
The list below gathers questions you can ask while planning a real-time feature. You do not need to answer yes to all of them. The goal is to spot the point you skipped.
- Does the data flow in both directions, or only from the server?
- Do updates arrive on the scale of seconds?
- Is wss your choice in production?
- Does the server check an allowed origin list?
- Are authentication and channel authorization defined?
- Is reconnection and missed message recovery logic in place?
- Does the load balancer support upgrade requests and long connections?
- If you have several servers, did you plan a message broker?
- Do you measure connection count, drops, and latency?
- Do you keep a durable record for important data?
Filling in this list together with your team in a meeting often exposes hidden assumptions.
How can our team support you with a WebSocket feature?
If you plan a feature such as live notifications, chat, or a dashboard, we can first clarify together whether you really need WebSocket. Sometimes a simple solution is enough. At other times, building the architecture right from the start saves a lot of time later.
We describe how we work on the custom software side on our custom software development page. For security details, our OWASP vulnerabilities guide is a good companion.
Also, the information in this article is general. For decisions about your own infrastructure, check current documentation and run real load tests.
Sources: the IETF document RFC 6455 for the protocol itself, the MDN WebSockets API page for the browser interface, the MDN guide to writing WebSocket servers, and the MDN page on Server-Sent Events.



