Skip to content

WebSocket Heartbeats — Complete Guide

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about WebSocket Heartbeats. We cover key concepts, practical examples, and best practices to help you master this topic.

WebSocket heartbeats use ping and pong frames to check connection health. The server sends periodic pings, and clients respond with pongs. Missing pongs indicate a dead connection that should be terminated and reconnected.

What You'll Learn

  • Ping-pong frame mechanism
  • Server-side heartbeat implementation
  • Client-side heartbeat handling
  • Heartbeat intervals and timeouts
  • Proxy and load balancer timeout considerations

Why It Matters

Network devices (proxies, load balancers) drop idle connections. Heartbeats keep connections alive and detect silent disconnections. Without heartbeats, zombie connections accumulate and waste resources.

Real-World Use

AWS ALB times out idle connections after 60 seconds. Cloudflare waits 60-90 seconds. Heartbeats at 30-second intervals prevent these timeouts and provide early failure detection.

sequenceDiagram
    Server->>Client: WebSocket Ping
    Client-->>Server: WebSocket Pong
    Note over Server: Wait pingInterval
    Server->>Client: WebSocket Ping
    Note over Client: Client lost network
    Server->>Client: WebSocket Ping
    Note over Server: pingTimeout expired
    Server->>Server: Close connection

Teacher Mindset

Heartbeats are essential for production WebSocket servers. Set ping intervals shorter than your proxy timeout. Set ping timeout to 2-3x the interval. Always handle pong responses to confirm client liveness.

Code Examples

// Example 1: Server-side heartbeat with ws library
const WebSocket = require('ws');

const server = new WebSocket.Server({
  port: 8080,
  pingInterval: 30000,
  pingTimeout: 5000
});

server.on('connection', (ws) => {
  console.log('Client connected');

  ws.on('pong', () => {
    console.log('Received pong from client');
    ws.isAlive = true;
  });

  ws.on('close', () => {
    console.log('Client disconnected');
  });
});

// Heartbeat check interval
const heartbeat = setInterval(() => {
  server.clients.forEach((ws) => {
    if (ws.isAlive === false) {
      console.log('Terminating dead connection');
      return ws.terminate();
    }

    ws.isAlive = false;
    ws.ping();
  });
}, 30000);

server.on('close', () => clearInterval(heartbeat));
// Example 2: Client-side heartbeat handler
const ws = new WebSocket('ws://localhost:8080');

ws.on('open', () => {
  console.log('Connected');
});

ws.on('ping', () => {
  // Automatically sends pong in the ws library
  console.log('Received ping, sending pong');
});

ws.on('close', () => {
  console.log('Connection closed by server heartbeat');
});
// Example 3: Socket.IO with heartbeat configuration
const io = require('socket.io')(3000, {
  pingInterval: 25000,
  pingTimeout: 20000
});

io.on('connection', (socket) => {
  console.log('Client connected');

  socket.on('disconnect', (reason) => {
    console.log('Disconnected:', reason);
    // "ping timeout" means heartbeat failed
  });
});

Common Mistakes

  • Setting ping interval longer than proxy/load balancer timeout
  • Not checking the pong response before terminating connections
  • Sending pings too frequently, generating unnecessary traffic
  • Not handling the ping event on the client side
  • Forgetting that Socket.IO has built-in ping-pong (configure pingInterval)

Practice

  1. Implement server-side heartbeat with 30s interval and 10s timeout.
  2. Verify that clients respond to pings with pongs.
  3. Simulate a network drop and verify the server terminates the connection.
  4. Configure Socket.IO heartbeat with custom intervals.
  5. Challenge: Build a heartbeat monitoring dashboard that shows alive/dead connection counts.

FAQ

What ping interval should I use?

25-30 seconds is standard. Set it lower than your proxy timeout (usually 60s).

What happens if a client does not respond to a ping?

After the pingTimeout, the server closes the connection. The client should detect this and reconnect.

Does WebSocket have built-in keepalive?

The WebSocket protocol supports ping-pong frames, but the server must initiate them. There is no automatic keepalive.

How does Socket.IO heartbeat work?

Socket.IO uses its own ping-pong mechanism with configurable pingInterval and pingTimeout.

Should I heartbeat from client or server?

The server should initiate heartbeats. The client responds to pings. Some architectures also use client-initiated heartbeats.

Mini Project

Configure heartbeats on your WebSocket server with 25s ping interval and 10s timeout. Add a connection health monitor that logs alive connections count every 30 seconds. Test that connections are terminated after 10 seconds without pong.

What's Next

Next, you will learn about integrating WebSocket with Express.js"Express" >}}.js.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro