Communication Protocols Suitable for a Chat System: WebSocket vs. Long Polling vs. gRPC
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)
// 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
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)
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)
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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →