Long-Polling

Protocols & Transport Security Notes Jan 6, 2025 JAVASCRIPT

Definition

Have you ever been waiting for an important package and kept checking the front door every few minutes? That’s frustrating and inefficient, right? Long-polling solves a similar problem in the digital world. Instead of your app constantly asking the server “anything new? anything new? anything new?” every second (which wastes resources and bandwidth), long-polling flips the script.

Here’s how it works: your app sends a request to the server asking for updates, but instead of the server immediately saying “nope, nothing yet,” it holds onto that request and waits. The server keeps the connection open, patiently listening for something interesting to happen. The moment new data arrives - maybe a chat message, a notification, or a stock price change - the server immediately sends it back to your app. If nothing happens after a set time (say 30 seconds), the server finally responds with “still nothing” and your app starts a new request.

This technique sits in a sweet spot between regular polling (inefficient constant checking) and WebSockets (more complex to implement). Long-polling gives you near real-time updates without requiring the infrastructure changes that WebSockets demand. It works with standard HTTP, passes through most firewalls and proxies without issues, and is supported everywhere. For many applications, it’s the perfect balance of simplicity and responsiveness.

Example

Long-polling is everywhere, even if you don’t notice it. Here are some real-world scenarios where you’ve probably experienced it:

Chat Applications: When you’re waiting for a message in a web-based chat app like the older versions of Facebook Messenger or Slack’s web client, long-polling keeps you connected. Your browser asks “any new messages?” and the server waits until someone actually sends you something before responding. That’s why messages seem to appear instantly even though you’re using plain old HTTP.

Live Sports Scores: Sports websites showing live scores often use long-polling. When you’re watching a football match and the score updates within seconds of a goal, long-polling is likely behind it. The page holds a connection open, waiting for the score to change, rather than refreshing every few seconds and missing the action.

Email Notifications: Gmail’s web interface historically used long-polling to show new emails. When someone sends you an email, it appears in your inbox almost immediately without you hitting refresh. The browser maintains a waiting request that springs to life the moment new mail arrives.

Collaborative Documents: Early versions of Google Docs used long-polling to show when collaborators were editing. The cursor movements and text changes from other users would appear smoothly because the server was holding connections open, ready to push updates the instant they happened.

Auction Sites: On eBay or similar auction platforms, long-polling helps display bid updates in real-time. When someone outbids you in the final seconds, you see it immediately because the server was holding your browser’s request, waiting for exactly that event.

Analogy

The Patient Librarian: Imagine you’re at a library and you’ve asked the librarian to let you know when a specific book becomes available. Instead of you coming back every 5 minutes to check (annoying for everyone), the librarian says “I’ll keep an eye on it - go sit down and read, and I’ll come find you the moment it’s returned.” You’re free to do other things, and the instant someone returns that book, the librarian taps your shoulder. That’s long-polling: the server (librarian) holds your request and only responds when there’s actually something to tell you.

The Restaurant Buzzer: When you’re waiting for a table at a busy restaurant, they give you one of those buzzer pagers. You don’t stand at the host stand asking “is my table ready?” every minute. Instead, you take the buzzer, go about your business, and the moment your table is free, it vibrates. Long-polling works the same way - your app “holds” a connection (like holding the buzzer), and the server only “buzzes” when something important happens.

The Fishing Rod: Think of long-polling like fishing. You cast your line into the water (send a request) and then wait patiently. You don’t constantly pull the line in and cast again every few seconds - that would scare the fish away and exhaust you. Instead, you leave the line in the water, alert and ready. The moment a fish bites (new data arrives), you feel it immediately and can react. If nothing bites after a while, you reel in and cast again (timeout and new request).

The Security Guard’s Radio: Picture a security guard with a walkie-talkie. When they press the button to call in, they don’t immediately hang up if there’s no response. They hold the line open for a reasonable time, listening for any response from headquarters. If something happens at the base, they hear about it immediately. If all stays quiet for too long, they release the button and try again later. That held-open communication channel is exactly what long-polling does.

Diagram

sequenceDiagram
    participant C as Client
    participant S as Server

    C->>S: GET /api/poll
    Note over S: Hold connection...
waiting for data Note over S: Still waiting... Note over S: Data arrives! S->>C: 200 OK {"message": "New data!"} Note over C: Immediately reconnect C->>S: GET /api/poll Note over S: Hold connection...
waiting for data Note over S: Still waiting... Note over S: Timeout (30s) S->>C: 200 OK (no data) Note over C: Immediately reconnect C->>S: GET /api/poll Note over S: Hold connection... Note over S: Data arrives! S->>C: 200 OK {"message": "Update!"} Note over C,S: Server holds request until
data is available or timeout

Code Example


// Client-side long-polling
async function longPoll() {
  try {
    const response = await fetch('/api/messages/poll', {
      method: 'GET',
      headers: { 'Content-Type': 'application/json' },
      // Server holds connection for up to 30s
    });

    const data = await response.json();
    if (data.messages) {
      processMessages(data.messages);
    }
  } catch (error) {
    console.error('Poll error:', error);
  }

  // Immediately poll again
  longPoll();
}

longPoll();

Security Notes

SECURITY NOTES

CRITICAL: Long polling maintains open connections. Resource-intensive; use WebSockets/SSE instead.

How Long Polling Works:

  • Client requests: Client sends request to server
  • Server waits: Server holds request waiting for data
  • Server responds: When data available, server responds
  • Client reconnects: Client immediately sends new request

Resource Costs:

  • Server memory: Each connection consumes server resources
  • Network overhead: Connection headers for each cycle
  • Latency: Delay between data availability and client receipt
  • Scalability: Limited by connection resources

Security:

  • Authentication: Each request must authenticate
  • Authorization: Verify user can receive updates
  • Rate limiting: Prevent connection exhaustion
  • Timeout: Close stale connections

Compared to Alternatives:

  • WebSockets: Bidirectional, lower overhead
  • SSE: Simpler than WebSockets, unidirectional
  • Webhooks: Push model, server-initiated
  • Polling: Frequent requests, polling on interval

Standards & RFCs

Standards & RFCs
2)Comet (programming) - Historical pattern documentation (no formal RFC)