Long Polling vs WebSocket in TypeScript: What to Choose for Real-Time?

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

When a "Live" Site Requires Live Code

\n

Imagine: you're writing a messenger in TypeScript. A user sends a message — and the recipient should see it instantly, without refreshing the page. Or a stock exchange dashboard where stock prices change every second. Or simply a notification feed that updates itself. How to implement this? Two main candidates are long polling and WebSocket. But which one to choose to avoid ruining performance and breaking UX?

\n

In this article, we will use real TypeScript examples to break down how each technology works, where they shine, and where they fall short. You'll get not only theory but also ready-made code snippets for Node.js and the browser. Let's go!

\n\n

What is Long Polling in TypeScript and How Does It Work

\n

Long polling is an evolution of a regular HTTP request. The client sends a request to the server, but the server does not respond immediately if there is no data. It keeps the connection open until a new event occurs. As soon as the data is ready — the server sends a response, the client processes it and immediately creates a new request. The cycle repeats.

\n

Sounds like a workaround? Partially, yes. But it works even through the strictest corporate proxies that block WebSocket.

\n\n

Implementing Long Polling in TypeScript (Server Side)

\n

Let's write a simple server using Express with TypeScript. It will emulate a message queue.

\n
import express, { Request, Response } from 'express';\nimport cors from 'cors';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\n// Message storage (queue simulation)\nconst messages: string[] = [];\n\n// Endpoint for long polling\napp.get('/poll', (req: Request, res: Response) => {\n  // Wait for a new message for up to 30 seconds\n  const checkForMessage = () => {\n    if (messages.length > 0) {\n      // Send the first message and remove it from the queue\n      const message = messages.shift();\n      res.json({ data: message, timestamp: Date.now() });\n    } else {\n      // If no messages — keep waiting\n      setTimeout(checkForMessage, 1000); // check every second\n    }\n  };\n\n  // Timeout in case there are no messages for a long time\n  const timeout = setTimeout(() => {\n    res.json({ data: null, timeout: true });\n  }, 30000);\n\n  // If the client disconnects — clear timers\n  req.on('close', () => {\n    clearTimeout(timeout);\n  });\n\n  checkForMessage();\n});\n\n// Endpoint for sending a message\napp.post('/send', (req: Request, res: Response) => {\n  const { message } = req.body;\n  if (message) {\n    messages.push(message);\n    res.status(200).json({ status: 'ok' });\n  } else {\n    res.status(400).json({ error: 'message is required' });\n  }\n});\n\napp.listen(3000, () => console.log('Long poll server on port 3000'));
\n\n

Client Side in TypeScript (Browser)

\n
async function startLongPolling() {\n  try {\n    const response = await fetch('http://localhost:3000/poll');\n    const data = await response.json();\n\n    if (data.data) {\n      console.log('New message:', data.data);\n      // Update UI\n      updateUI(data.data);\n    }\n\n    // Immediately start a new poll\n    startLongPolling();\n  } catch (error) {\n    console.error('Long polling error:', error);\n    // Wait 2 seconds and try again\n    setTimeout(startLongPolling, 2000);\n  }\n}\n\nfunction updateUI(message: string) {\n  // Your code for updating the DOM\n  const container = document.getElementById('messages');\n  if (container) {\n    const item = document.createElement('li');\n    item.textContent = message;\n    container.appendChild(item);\n  }\n}\n\n// Start on page load\ndocument.addEventListener('DOMContentLoaded', startLongPolling);
\n

Conclusion: long polling is simple to implement and does not require special protocols. But each request involves HTTP headers, cookies, and overhead. With 1000 simultaneous clients

Blogs

Book Recommendations