Skip to content

WebSockets vs Long Polling: From Legacy to Real-Time

Quick Summary

Long polling was the original hack for real-time web communication before WebSockets existed. While it simulates real-time updates through clever use of HTTP requests, WebSockets provide true bidirectional, persistent connections with significantly better performance and resource efficiency. Today, long polling primarily serves as a fallback mechanism for environments where WebSockets aren’t available.

At a Glance Comparison

FeatureLong PollingWebSockets
Connection TypeHTTP Request/Response cyclesPersistent TCP connection
DirectionClient-initiated onlyTrue bidirectional
Real-timeSimulated (polling delays)Native real-time
Protocol OverheadHigh (HTTP headers each request)Low (after handshake)
Server ResourcesHigh (connection churn)Efficient (persistent)
Client BatteryHigh drain (constant requests)Low drain
Firewall Friendly✅ Yes (standard HTTP)Usually (port 80/443)
Proxy Support✅ ExcellentGood with modern proxies
Browser Support100%99%+
ComplexityMediumLow-Medium
Message OrderingCan be problematicGuaranteed
Connection StateStatelessStateful

How Long Polling Works

Long polling extends the traditional request-response model by holding HTTP connections open until the server has data to send:

  1. Client makes request: Opens standard HTTP connection
  2. Server holds connection: Doesn’t respond immediately
  3. Event occurs: Server sends response with data
  4. Client reconnects: Immediately opens new request
  5. Cycle repeats: Creates illusion of real-time

The Long Polling Lifecycle

// Client-side long polling implementation
class LongPoller {
constructor(url) {
this.url = url;
this.polling = false;
}
async start() {
this.polling = true;
while (this.polling) {
try {
// Make request and wait for response
const response = await fetch(this.url, {
method: 'GET',
// Long timeout to hold connection
signal: AbortSignal.timeout(30000)
});
if (response.ok) {
const data = await response.json();
this.onMessage(data);
}
} catch (error) {
if (error.name === 'AbortError') {
// Timeout is normal, just reconnect
} else {
// Real error, wait before retry
await this.delay(1000);
}
}
// Immediately reconnect for next message
}
}
stop() {
this.polling = false;
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
onMessage(data) {
console.log('Received:', data);
}
}

Server-Side Long Polling

const express = require('express');
const app = express();
// Store pending requests
const pendingRequests = new Map();
app.get('/poll', (req, res) => {
const clientId = req.query.clientId || generateId();
// Store response object to send data later
pendingRequests.set(clientId, res);
// Set timeout to prevent infinite hanging
const timeout = setTimeout(() => {
if (pendingRequests.has(clientId)) {
res.json({ type: 'timeout' });
pendingRequests.delete(clientId);
}
}, 30000);
// Clean up on client disconnect
req.on('close', () => {
clearTimeout(timeout);
pendingRequests.delete(clientId);
});
});
// When event occurs, notify waiting clients
function broadcastMessage(message) {
pendingRequests.forEach((res, clientId) => {
res.json({ type: 'message', data: message });
pendingRequests.delete(clientId);
});
}

How WebSockets Work

WebSockets establish a persistent, full-duplex connection through an HTTP upgrade:

// Client-side WebSocket - Simple and efficient
const ws = new WebSocket('wss://example.com/socket');
ws.onopen = () => {
console.log('Connected once');
ws.send('Hello Server');
};
ws.onmessage = (event) => {
console.log('Received:', event.data);
// Server can push at any time
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected');
// Implement reconnection logic
};
// Send multiple messages over same connection
ws.send('Message 1');
ws.send('Message 2');
// No HTTP overhead, just frame headers

Key Differences

Connection Management

Long Polling: Constant connection cycling

  • New TCP connection for each poll
  • TCP handshake overhead repeated
  • Connection state lost between requests
  • Session management complexity

WebSockets: Single persistent connection

  • One TCP connection maintained
  • Handshake happens once
  • Stateful connection
  • Simple session tracking

Message Delivery Timing

Long Polling: Potential delays

  • Message arrives while client reconnecting = delay
  • Timeout cycles can miss messages
  • Race conditions possible
  • Ordering issues with concurrent requests

WebSockets: Immediate delivery

  • Messages pushed instantly
  • No reconnection gaps
  • Guaranteed message ordering
  • No timing issues

Resource Usage

Long Polling creates significant overhead:

  • Each poll cycle requires new HTTP headers (500-2000 bytes)
  • Server must handle connection churn
  • Client CPU usage for constant reconnection
  • Network overhead for TCP handshakes

WebSockets are efficient:

  • Minimal frame overhead (2-14 bytes)
  • Single connection to maintain
  • Lower CPU usage on both ends
  • Reduced network traffic

Implementation Complexity

Long Polling requires handling:

  • Reconnection logic
  • Timeout management
  • Message queueing
  • Duplicate detection
  • Connection tracking
  • Error recovery

WebSockets simplify development:

  • Built-in connection management
  • Native browser API
  • Straightforward error handling
  • Simple message passing
  • Library ecosystem mature

Use Case Analysis

When Long Polling Might Still Apply

✅ Restricted environments:

  • Corporate firewalls blocking WebSocket
  • Legacy proxy servers
  • Environments with WebSocket issues

✅ Simple notification systems:

  • Infrequent updates
  • One-way server notifications
  • Fallback mechanism

✅ Compatibility requirements:

  • Supporting ancient browsers
  • Maximum compatibility needed
  • Simple HTTP-only infrastructure

When WebSockets Excel

✅ Real-time applications:

  • Chat and messaging
  • Live collaboration
  • Gaming and interactive apps
  • Financial trading platforms
  • Live sports updates
  • IoT data streams

✅ High-frequency updates:

  • Monitoring dashboards
  • Real-time analytics
  • Location tracking
  • Sensor data
  • Live feeds

✅ Bidirectional communication:

  • Interactive features
  • User presence
  • Collaborative editing
  • Remote control
  • Video/audio signaling

Implementation Examples

Fallback Pattern: WebSocket with Long Polling Fallback

class RealTimeConnection {
constructor(wsUrl, pollUrl) {
this.wsUrl = wsUrl;
this.pollUrl = pollUrl;
this.useWebSocket = this.supportsWebSocket();
}
supportsWebSocket() {
return 'WebSocket' in window &&
window.WebSocket.CLOSING === 2;
}
connect() {
if (this.useWebSocket) {
this.connectWebSocket();
} else {
console.log('WebSocket not available, using long polling');
this.startLongPolling();
}
}
connectWebSocket() {
this.ws = new WebSocket(this.wsUrl);
this.ws.onopen = () => {
console.log('WebSocket connected');
this.onConnect();
};
this.ws.onmessage = (event) => {
this.onMessage(JSON.parse(event.data));
};
this.ws.onerror = () => {
// Could fall back to polling here
console.log('WebSocket error, attempting reconnect');
setTimeout(() => this.connectWebSocket(), 1000);
};
}
startLongPolling() {
this.polling = true;
this.poll();
}
async poll() {
while (this.polling) {
try {
const response = await fetch(this.pollUrl);
const data = await response.json();
if (data.type !== 'timeout') {
this.onMessage(data);
}
} catch (error) {
await this.delay(1000);
}
}
}
send(message) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
} else {
// For polling, need separate endpoint
fetch(this.pollUrl, {
method: 'POST',
body: JSON.stringify(message)
});
}
}
onConnect() {
console.log('Connected');
}
onMessage(data) {
console.log('Message received:', data);
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage
const connection = new RealTimeConnection(
'wss://api.example.com/socket',
'https://api.example.com/poll'
);
connection.connect();

The Evolution: Why WebSockets Won

Historical Context

Long polling emerged in the early 2000s as a clever workaround for the web’s request-response limitations. Technologies like Comet, BOSH, and Bayeux all used variations of long polling to simulate real-time communication.

WebSockets, standardized in 2011, provided what developers actually needed: a proper bidirectional communication protocol designed for real-time from the ground up.

Technical Advantages of WebSockets

  1. Protocol Efficiency: Purpose-built for real-time communication
  2. Native Browser Support: No hacks or workarounds needed
  3. Standardized: RFC 6455 provides clear implementation guidelines
  4. Ecosystem: Mature libraries and tools available
  5. Performance: Lower latency, less overhead, better scaling

Modern Reality

Today, WebSockets are supported by 99%+ of browsers and all major server platforms. The reasons to use long polling have largely disappeared except for specific edge cases or as a fallback mechanism.

Working with WebSocket Providers

While raw WebSocket implementation is straightforward, production deployments benefit from using established protocols and services:

Open Source Solutions like Socket.IO provide:

  • Automatic fallback to long polling
  • Reconnection handling
  • Room/namespace abstractions
  • Built-in message acknowledgments

Commercial Services like Ably offer:

  • Global infrastructure
  • Automatic scaling
  • Connection state recovery
  • Message ordering guarantees
  • Multiple protocol support

These solutions abstract away the complexities of managing WebSocket infrastructure while providing robust handling of edge cases and failure scenarios. For most applications, using a WebSocket-based service or library is recommended over implementing raw WebSocket protocols.

Conclusion

Long polling served its purpose in the evolution of real-time web technologies, but WebSockets have definitively superseded it for modern applications. The efficiency, simplicity, and performance benefits of WebSockets make them the clear choice for real-time communication.

Key Takeaways:

  1. WebSockets are superior for real-time communication in almost every metric
  2. Long polling is legacy technology, useful mainly as a fallback
  3. Modern browsers have excellent WebSocket support (99%+)
  4. Using WebSocket providers simplifies implementation and improves reliability
  5. The complexity of long polling isn’t worth it for new projects

For new projects requiring real-time features, WebSockets should be your default choice. The ecosystem is mature, support is universal, and the performance benefits are significant.

Further Reading

For production-ready WebSocket infrastructure with automatic fallbacks and global scale, explore Ably’s platform.


Written by Matthew O’Riordan, Co-founder & CEO of Ably, with experience building real-time systems reaching 2 billion+ devices monthly.