Pular para o conteúdo principal

Protocol Comparison

Choose the right streaming protocol for your use case.

Compare Live

Open Comparison Client — See all protocols side-by-side in real-time!

Quick Comparison

FeatureNATS WSWebSocketWebTransportSSEREST API
DirectionBidirectionalBidirectionalBidirectionalServer → ClientRequest/Response
ProtocolWebSocketTCPWS + QUIC (via Centrifugo)HTTPHTTP
Latency<1ms1-5ms~10ms10-50ms50-200ms
Overhead~20 bytes2-14 bytes~30 bytes~50 bytes~200 bytes
ReconnectionConfigurableManualAutomaticAutomaticN/A
Multiple streamsVia subjectsNoVia channelsNoN/A
WildcardsYesNoNoNoNo
Direct brokerYesNoNoNoNo
Browser supportES ModulesUniversalUniversal (fallback)IE exceptUniversal
Proxy-friendlySometimesSometimesYes (via Centrifugo)AlwaysAlways

Detailed Analysis

Connection Establishment

Protocol Connection

Message Overhead

ProtocolFrame FormatOverhead
WebTransport[Length] + Payload2-6 bytes
NATS WS[Subject][Payload]~20 bytes
WebSocket[FIN][RSV][Opcode][Mask][Len] + Payload2-14 bytes
SSEevent: message\ndata: {...}\n\n~50 bytes
REST APIHTTP Headers + Body~200 bytes

Use Case Matrix

Use CaseRecommendedWhy
DashboardSSEAuto-reconnect, simple
ChatWebSocketBidirectional needed
GamingNATSUltra-low latency, direct broker
NotificationsSSEServer push only
TradingNATSLowest latency critical
Live scoresSSESimple, reliable
Multi-game monitoringNATSWildcard subscriptions
Collaborative editingWebSocketBidirectional, reliable
Scalable real-timeWebTransportHorizontal scaling, auto-reconnect
History queriesREST APIRequest/response, caching
Polling fallbackREST APIUniversal compatibility

Decision Tree

Protocol Decision Tree

Performance Benchmarks

Latency (ms)

ProtocolP50P95P99
NATS WS0.91.82.8
WebSocket2.14.88.2
WebTransport (Centrifugo)8.015.022.0
SSE15.338.262.1
REST API65.0120.0180.0

Throughput (messages/second)

ProtocolSingle Connection1000 Connections
NATS WS70,00065,000
WebSocket50,00045,000
WebTransport (Centrifugo)60,00055,000
SSE20,00018,000
REST API100,00090,000

Memory Usage (per connection)

ProtocolIdleActive
SSE4 KB8 KB
WebSocket8 KB16 KB
NATS WS10 KB18 KB
WebTransport (Centrifugo)12 KB20 KB

Browser Compatibility

WebSocket

BrowserVersionSupport
Chrome4+
Firefox11+
Safari5+
Edge12+
IE10+
iOS Safari4.2+
Android4.4+

SSE

BrowserVersionSupport
Chrome6+
Firefox6+
Safari5+
Edge79+
IE-
iOS Safari5+
Android4.4+

WebTransport

BrowserVersionSupport
Chrome97+
Firefox114+
Safari-
Edge97+
IE-
iOS Safari-
Android Chrome97+

Infrastructure Considerations

ProtocolProsCons
WebTransportBest performance, multiple streams, unreliable deliveryRequires UDP, limited proxy/CDN support
NATS WSDirect broker, wildcards, low latencyRequires NATS port exposure, ES modules
WebSocketWorks with most LBs, nginx/HAProxy/Cloudflare supportMay need sticky sessions, proxy timeout issues
SSEStandard HTTP everywhere, no special config, CDN-friendly6 conn/domain (HTTP/1.1), unidirectional
REST APIUniversal, cacheable, statelessPolling overhead, higher latency

Code Examples

Unified Client

class StreamClient {
constructor(game, options = {}) {
this.game = game;
this.protocol = options.protocol || 'auto';
this.onMessage = options.onMessage || console.log;
this.connection = null;
}

async connect() {
switch (this.protocol) {
case 'websocket':
return this.connectWebSocket();
case 'sse':
return this.connectSSE();
case 'webtransport':
return this.connectWebTransport();
case 'auto':
default:
return this.connectAuto();
}
}

async connectAuto() {
// Try WebTransport first (best performance)
if (typeof WebTransport !== 'undefined') {
try {
await this.connectWebTransport();
return;
} catch (e) {
console.log('WebTransport unavailable, trying WebSocket');
}
}

// Fallback to WebSocket
try {
await this.connectWebSocket();
} catch (e) {
console.log('WebSocket unavailable, trying SSE');
await this.connectSSE();
}
}

connectWebSocket() {
return new Promise((resolve, reject) => {
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = new WebSocket(`${proto}//${location.host}/ws/${this.game}`);

ws.onopen = () => {
this.connection = ws;
resolve();
};

ws.onmessage = (e) => {
this.onMessage(JSON.parse(e.data));
};

ws.onerror = reject;
});
}

connectSSE() {
return new Promise((resolve) => {
const sse = new EventSource(`/sse/${this.game}`);
this.connection = sse;

sse.onopen = resolve;

sse.addEventListener('message', (e) => {
this.onMessage(JSON.parse(e.data));
});

sse.addEventListener('initial', (e) => {
this.onMessage(JSON.parse(e.data));
});
});
}

async connectWebTransport() {
// WebTransport via Centrifugo with automatic fallback
const transports = [];

if (typeof WebTransport !== 'undefined') {
transports.push({
transport: 'webtransport',
endpoint: 'https://wt.datastream.hypetech.games/connection/webtransport'
});
}
transports.push({
transport: 'websocket',
endpoint: 'wss://wt.datastream.hypetech.games/connection/websocket'
});

const centrifuge = new Centrifuge(transports);

centrifuge.on('connected', () => {
const channel = `stream:${this.game}`;
const sub = centrifuge.newSubscription(channel);
sub.on('publication', (ctx) => this.onMessage(ctx.data));
sub.subscribe();
});

centrifuge.connect();
this.connection = centrifuge;
}

disconnect() {
if (this.connection) {
if (this.connection.close) {
this.connection.close();
}
}
}
}

// Usage
const client = new StreamClient('crash', {
protocol: 'auto',
onMessage: (data) => {
console.log(`Round ${data.round_id}: ${data.extras}`);
}
});

await client.connect();

Recommendations

For Most Applications

Use SSE as the default choice:

  • Simplest to implement
  • Best proxy compatibility
  • Auto-reconnection
  • Sufficient for most real-time needs

For Interactive Applications

Use WebSocket when:

  • Client needs to send data
  • Bidirectional communication required
  • Gaming, chat, collaboration

For Direct Broker Access

Use NATS WebSocket when:

  • Need wildcard subscriptions (e.g., all games)
  • Want lowest latency without backend hop
  • Building internal dashboards
  • Have NATS port accessible to clients

For Scalable Real-time

Use WebTransport (via Centrifugo) when:

  • You need horizontal scaling via Redis
  • You want automatic reconnection
  • You need universal browser support (automatic WebSocket fallback)
  • You want managed real-time infrastructure

For Universal Compatibility

Use REST API when:

  • Need historical data
  • Building mobile apps
  • Caching is important
  • Real-time not required
  • Fallback for streaming protocols

Protocol Selection Flowchart

Protocol Selection Flowchart