# Communication Protocols Suitable for a Chat System: WebSocket vs. Long Polling vs. gRPC

> Discover the best communication protocols for chat systems. Learn why WebSocket excels for real-time chat and explore alternatives like Long Polling and gRPC for specific needs.

- Repository: [Gaurav Kumar/system-design-notes](https://github.com/liquidslr/system-design-notes)
- Tags: deep-dive
- Published: 2026-09-09

---

**WebSocket is the optimal communication protocol for real-time chat systems, providing full-duplex, low-latency connections capable of scaling to 50 million daily active users, while Long Polling, Server-Sent Events, gRPC, and MQTT serve specific fallback or specialized use cases.**

Designing a real-time chat system requires selecting transport protocols that balance latency, scalability, and infrastructure complexity. The `liquidslr/system-design-notes` repository outlines a comprehensive architecture in `12. Chat System/Readme.md` that evaluates multiple communication protocols suitable for a chat system before selecting WebSocket as the primary transport layer for bidirectional messaging.

## Primary Protocol: WebSocket for Real-Time Messaging

According to `12. Chat System/Readme.md` (lines 31-55), the architecture adopts **WebSocket** (`ws`/`wss`) as the default protocol for both sending and receiving messages. This full-duplex TCP connection enables sub-millisecond latency and bi-directional frame transmission without the overhead of HTTP headers per message.

The design deploys **stateful chat servers** that maintain persistent WebSocket connections (lines 70-72). Unlike stateless HTTP architectures, these servers keep socket descriptors in memory, mapping user IDs to specific server instances. To scale beyond single-node limitations, the system implements user-hash based sharding and service discovery via **Zookeeper** (lines 118-121), supporting architectures handling 50 million daily active users.

## Alternative Communication Protocols

While WebSocket serves as the primary transport, the repository outlines several alternative protocols suitable for specific requirements and legacy compatibility.

### HTTP Long Polling

This approach holds client requests open until new messages arrive, then immediately re-issues the request. While compatible with standard HTTP/1.1 infrastructure and easy to implement behind corporate proxies, it introduces higher latency during sparse message periods and consumes more bandwidth due to repeated headers.

The repository explicitly mentions **Polling** and **Long Polling** as less efficient alternatives (lines 38-47) suitable only for graceful degradation paths supporting legacy browser clients that cannot establish WebSocket connections.

### Server-Sent Events (SSE)

SSE provides unidirectional server-to-client streaming over HTTP/1.1 using the browser's `EventSource` API. It simplifies implementation for push-only notifications like typing indicators or online presence updates, featuring automatic reconnection capabilities.

However, SSE cannot handle client-to-server messaging over the same channel, requiring separate HTTP POST requests for outgoing chat messages. It also lacks support for binary data transmission, limiting its utility for file-sharing features.

### gRPC over HTTP/2

For microservice back-end communication, **gRPC** offers strongly typed contracts via Protocol Buffers and bi-directional streaming via HTTP/2 multiplexing. The framework provides built-in flow control and efficient binary serialization.

Nevertheless, gRPC requires heavyweight tooling for protobuf definitions and presents browser compatibility challenges without gRPC-Web shims. According to the system design notes, gRPC suits internal service-to-service communication where chat logic is encapsulated in RPC services, rather than direct client-to-server browser connections.

### MQTT

The **MQTT** protocol excels for mobile and IoT clients with intermittent connectivity or constrained bandwidth. Running over TCP or WebSocket transports, it provides lightweight publish/subscribe messaging with configurable Quality of Service (QoS) levels through brokers like Mosquitto.

While ideal for mobile apps with sporadic network availability, MQTT's topic-based routing architecture may introduce unnecessary complexity for simple peer-to-peer chat scenarios. The system design suggests employing MQTT when targeting resource-constrained environments or IoT telemetry integrations.

## Implementation Examples

### WebSocket Client (Browser)

```javascript
// Establish a persistent WebSocket connection
const socket = new WebSocket('wss://chat.example.com/ws');

// Connection opened
socket.addEventListener('open', () => {
  console.log('WebSocket connection established');
  // Send a chat message
  socket.send(JSON.stringify({ to: 'userB', text: 'Hello!' }));
});

// Receive a message
socket.addEventListener('message', event => {
  const msg = JSON.parse(event.data);
  console.log('New message from', msg.from, ':', msg.text);
});

```

### Long Polling Fallback

```javascript
async function pollMessages() {
  while (true) {
    const response = await fetch('/messages?since=' + lastSeenId);
    const msgs = await response.json();
    msgs.forEach(m => display(m));
    // Short delay before next poll to avoid hammering the server
    await new Promise(r => setTimeout(r, 2000));
  }
}
pollMessages();

```

### gRPC Server Stream (Go)

```go
type ChatService struct{ pb.UnimplementedChatServer }

func (s *ChatService) StreamMessages(req *pb.StreamRequest, stream pb.Chat_StreamMessagesServer) error {
    for {
        msg := <-messageChannel // receive from internal broker
        if err := stream.Send(msg); err != nil {
            return err
        }
    }
}

```

### MQTT Client (Node.js)

```javascript
const mqtt = require('mqtt');
const client = mqtt.connect('ws://mqtt-broker.example.com:8080');

client.on('connect', () => {
  client.subscribe('chat/userA');
  client.publish('chat/userB', 'Hello from A');
});

client.on('message', (topic, payload) => {
  console.log(`Received on ${topic}: ${payload.toString()}`);
});

```

## Summary

- **WebSocket** provides the optimal balance of latency and bi-directional capability for real-time chat, as specified in `12. Chat System/Readme.md` (lines 31-55).
- **Stateful server architecture** with Zookeeper service discovery enables horizontal scaling to 50 million daily active users (lines 70-72, 118-121).
- **Long Polling and Polling** serve as HTTP/1.1 compatible fallbacks for legacy clients unable to support WebSocket (lines 38-47).
- **SSE** suits unidirectional server-to-client streams, while **gRPC** fits microservice internals, and **MQTT** targets mobile/IoT constraints requiring QoS guarantees.

## Frequently Asked Questions

### Why is WebSocket preferred over HTTP Long Polling for chat applications?

WebSocket maintains persistent full-duplex connections that eliminate the repeated HTTP header overhead and connection establishment latency inherent in Long Polling. As documented in `12. Chat System/Readme.md`, this reduces round-trip overhead and supports sub-millisecond latency required for high-frequency chat traffic and presence updates.

### When should I use Server-Sent Events instead of WebSocket?

Use SSE when your application only requires server-to-client streaming, such as live notifications or typing indicators, and can send client messages via separate HTTP POST requests. SSE operates over standard HTTP/1.1 with automatic reconnection capabilities, making it simpler to implement than WebSocket for unidirectional data flows where client uploads are infrequent.

### Can gRPC replace WebSocket for browser-based chat clients?

gRPC is not ideal for direct browser-based chat without gRPC-Web shims due to limited native browser support and dependency on HTTP/2 trailers. According to the system design notes, gRPC excels in microservice back-end communication where chat logic is encapsulated in RPC services, while WebSocket remains superior for direct client connections requiring minimal latency.

### How does MQTT fit into mobile chat application architecture?

MQTT suits mobile chat clients with intermittent connectivity or limited bandwidth, offering lightweight publish/subscribe mechanisms with configurable QoS levels. The protocol requires a broker layer (e.g., Mosquitto) and can run over WebSocket transports, making it viable for IoT integrations or resource-constrained mobile environments where connection stability varies.