Web Development11 November 2025·11 min read

Building Real-Time Applications with WebSockets and Next.js

WebSocket fundamentals, Socket.io vs native WebSockets, implementing chat and live dashboards, scaling strategies, and fallback patterns for real-time apps.

WebSocketsSocket.ioReal-TimeNext.jsChatLive Dashboard

Why WebSockets Matter

HTTP is request-response. The client asks, the server answers. For real-time features — live chat, collaborative editing, stock tickers, multiplayer games, live dashboards — this model falls short. Polling (asking the server every N seconds) wastes bandwidth and introduces latency. Server-Sent Events work for one-way streams but not bidirectional communication.

WebSockets establish a persistent, full-duplex connection between client and server. Once opened, both sides can send messages at any time without the overhead of HTTP headers. A single WebSocket frame is as small as 2 bytes.

WebSocket Basics

The WebSocket protocol (RFC 6455) starts with an HTTP upgrade handshake. The client sends an Upgrade: websocket header, the server responds with 101 Switching Protocols, and the connection upgrades from HTTP to WebSocket. From this point, both sides communicate over the same TCP connection.

Key Concepts

Connection lifecycle: open, message, error, close events
Frames: Messages are sent as frames. Text frames carry UTF-8 strings. Binary frames carry arbitrary data.
Ping/Pong: Keep-alive mechanism to detect dead connections. The server sends a ping, the client responds with pong.
Close handshake: Either side can initiate a graceful close with a status code and reason string.

Socket.io vs Native WebSockets

Native WebSocket API

The browser's built-in WebSocket API is simple: new WebSocket(url), then listen for onopen, onmessage, onerror, and onclose events. Send messages with socket.send(data).

Advantages: No dependencies, smallest bundle size, direct control over the protocol.

Disadvantages: No automatic reconnection, no room/namespace support, no fallback for environments that block WebSockets, no built-in message acknowledgment.

Socket.io

Socket.io is a library that wraps WebSockets with additional features:

Automatic reconnection: Reconnects with exponential backoff when the connection drops.
Rooms and namespaces: Organize connections into logical groups. Broadcast to all users in a chat room without managing connection lists manually.
Fallback transports: Falls back to HTTP long-polling when WebSockets are blocked (corporate firewalls, some mobile networks).
Acknowledgments: Callback-based message confirmation. Know when the server received and processed your message.
Binary support: Seamless handling of binary data alongside text.

Our recommendation: Use Socket.io for production applications. The reconnection handling and room support alone justify the 40KB bundle addition.

Implementing Real-Time Chat

A basic real-time chat with Next.js and Socket.io requires:

Server Setup

Create a custom server (server.ts) that initializes both the Next.js app and a Socket.io server on the same port. Listen for connection events, then within each connection listen for join-room, leave-room, and send-message events. Broadcast received messages to all other users in the same room using socket.to(room).emit().

Client Setup

In your React client component, initialize the Socket.io client with useEffect. Connect to the server, join a room, and listen for incoming messages. Store messages in state and render them. Send messages through socket.emit("send-message", { room, text }).

Message Persistence

For production chat, persist messages to a database. When a user joins a room, fetch recent message history from PostgreSQL. New messages are saved to the database and simultaneously broadcast via Socket.io.

Building Live Dashboards

Real-time dashboards push data updates to connected clients as they happen:

Server-side: A background process monitors data changes (database polling, webhook listeners, or change data capture). When data changes, emit an event to connected dashboard clients.
Client-side: Subscribe to specific metric channels. Update charts and counters in real-time as events arrive.
Throttling: Batch updates into 1-second windows to prevent overwhelming the UI with per-millisecond updates.

Scaling WebSockets

A single Node.js process handles approximately 10,000-50,000 concurrent WebSocket connections depending on message volume and server resources. For larger scale:

Redis adapter: Socket.io's Redis adapter enables multiple server instances to share connection state. A message emitted on one server is broadcast to clients connected to other servers.
Sticky sessions: WebSocket connections must maintain affinity to a single server instance. Configure your load balancer for sticky sessions based on the connection ID.
Horizontal scaling: Add more server instances behind the load balancer. Each instance handles a portion of connections, coordinated through Redis.

Fallback Strategies

Not all environments support WebSockets reliably:

Corporate proxies: Some proxies terminate WebSocket connections. Socket.io's HTTP long-polling fallback handles this transparently.
Mobile networks: Cellular network switches can drop WebSocket connections. Implement reconnection with exponential backoff.
Server-Sent Events: For one-directional data (server to client only), SSE is simpler than WebSockets and works through more proxies.

Real-time features transform static applications into living, interactive experiences. Want to build real-time into your product? Get in touch.

BH

The Beyond Horizon Team

We are a digital agency based in Ajmer, India, specializing in Next.js web applications, React Native mobile apps, and UI/UX design. 150+ projects delivered.

About Us →

Have a project in mind?

We build fast, SEO-ready web and mobile applications.

Get a Free Consultation