KAHIBARO
Discord Login Register

27.10. Real-Time Applications

Understanding Real-Time Applications

Real-time applications are systems where users see updates almost immediately after something happens, without needing to refresh the page or send a new request manually.

In a classic request-response model, the client asks for data, the server answers, and that is it. In a real-time application, the server can also push new data to the client as soon as it is available.

Common examples:

Real-time does not mean “literally instant.” It normally means “fast enough that users perceive it as immediate,” usually within a few hundred milliseconds.

Key idea: A real-time app is one where the server can deliver new data to the client as soon as it exists, without the client asking for it each time.

Patterns for Real-Time Communication

There are several ways to build real-time features on top of HTTP and related technologies.

1. Polling

Polling is the simplest strategy. The client asks the server for new data every few seconds.

Example:

Pseudocode in JavaScript:

js
async function pollNotifications() {
  const response = await fetch('/notifications');
  const data = await response.json();
  renderNotifications(data);
  setTimeout(pollNotifications, 2000); // repeat after 2 seconds
}
pollNotifications();

Pros:

Cons:

Polling is acceptable when:

2. Long Polling

Long polling keeps the same idea as polling, but reduces needless requests.

Flow:

  1. Client sends GET /events.
  2. Server:
    • If there is an event, returns it immediately.
    • If there is no event yet, keeps the request open for some time (for example 30 seconds).
  3. If a new event appears while the request is open, the server returns it at once.
  4. If no event appears in 30 seconds, the server returns an empty response or timeout.
  5. Client immediately sends another GET /events.

This way, during quiet periods, there is at most one open request instead of many idle requests.

Pros:

Cons:

3. Server-Sent Events (SSE)

SSE uses a single long-lived HTTP connection from client to server, where the server streams events as text.

Characteristics:

  Content-Type: text/event-stream
  Cache-Control: no-cache
  Connection: keep-alive
  event: message
  data: {"text": "Hello"}
  event: count
  data: 42

Client example (browser):

js
const source = new EventSource('/events');
source.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('New message:', data);
};
source.addEventListener('count', (event) => {
  console.log('Count event', event.data);
});

Pros:

Cons:

SSE is great for:

4. WebSockets

WebSockets provide a bidirectional connection between client and server.

This enables:

The difference from SSE:

FeatureSSEWebSockets
DirectionServer to client onlyBoth client and server
TransportHTTP text streamWebSocket protocol on top of TCP
Browser APIEventSourceWebSocket
ComplexitySimpleMore complex
Good forNotifications, feedsChat, games, collaborative apps

Real-Time vs REST APIs

REST APIs:

Real-time channels (WebSockets or SSE):

In real applications you often use both:

Example flow in a chat app:

  1. User sends a message: POST /messages (REST).
  2. Server saves it to the database.
  3. Server publishes “new message” event to a message broker.
  4. A WebSocket server receives the event.
  5. WebSocket server sends the new message to all connected clients in that chat room.

This keeps your API simple and still gives real-time UX.

Core Design Challenges in Real-Time Apps

Real-time apps bring new challenges that are less visible in plain REST APIs.

Connection Management

You must handle:

Typical patterns:

Example heartbeat flow:

  1. Every 20 seconds, server sends: { "type": "ping" }.
  2. Client responds with { "type": "pong" }.
  3. If server does not receive pong after some time, it closes the connection.

Identifying Users and Sessions

You still need authentication and authorization, but now the connection lives a long time.

Common approaches:

Example WebSocket URL with token in query (simplified):

wss://api.example.com/ws/chat?token=abc123

Better options are usually:

Never trust data inside the message alone. Validate tokens during connection and, for long-lived connections, consider revalidating if tokens expire.

Rooms, Topics, and Subscriptions

Real-time apps often have the idea of “who should receive which messages.”

Common patterns:

Examples:

To support this, your server keeps an in-memory mapping:

When a new event arrives, you look up the correct group and send messages only to those connections.

Ordering and Idempotency

Messages may arrive:

To handle this safely:

Example:

Scaling Real-Time Connections

One server process can usually handle many open connections, especially with asynchronous frameworks. But for large systems you need multiple servers.

Problem:

Solution:

This is a classic pattern for real-time systems.

Example Architectures for Real-Time Features

Example: Chat Feature

Let us design a simple chat backend at a high level.

Components:

Flow for sending a message:

  1. Client sends POST /rooms/5/messages with JSON { "text": "Hello" }.
  2. API:
    • Checks permissions.
    • Saves message to messages table with room_id = 5.
    • Publishes a message to Redis channel room.5 with message data.
  3. Each WebSocket server is subscribed to room.5 in Redis.
  4. WebSocket server receives the event and sends it to all clients connected to /ws/rooms/5.

Flow for receiving messages:

  1. User connects: ws://.../ws/rooms/5.
  2. Server authenticates and registers connection in room 5.
  3. When Redis publishes room.5 events, server forwards them to all room 5 connections.

This setup allows many servers to share the same chat rooms.

Example: Live Metrics Dashboard with SSE

Goal:

Components:

Flow:

  1. Browser uses new EventSource('/metrics/stream').
  2. Server sets Content-Type: text/event-stream and flushes data every second:
   event: cpu
   data: {"server":"api-1","usage":57}
   event: cpu
   data: {"server":"api-2","usage":44}
  1. Client JavaScript updates dashboard graphs on each event.

This is one-way streaming from server to client, using a simple HTTP connection.

Handling Failures and Reconnection

Real-time connections are more fragile than simple HTTP requests. Networks drop, Wi-Fi jumps between routers, laptops sleep and wake.

You need strategies for:

Reconnection Strategies

Client logic should:

  1. Try to reconnect automatically if the connection is lost.
  2. Use increasing delays between attempts to avoid flooding the server.

Example simple strategy:

This is called exponential backoff.

Resynchronizing State

When reconnection happens, client may have missed events.

Patterns:

The key idea is that real-time channels are best-effort, and the source of truth is usually a database behind a REST API.

Choosing the Right Technology

Use this table as a guide:

RequirementTechnique to consider
Rare updates, delay of seconds is fineSimple polling
Frequent updates, still simple setupLong polling
Server-only push (notifications, dashboards)SSE
Two-way communication (chat, games)WebSockets
Many servers, high scaleWebSockets + broker (Redis, Kafka)
Streaming text or logsSSE or WebSockets

Often you will mix them:

Data Formats and Message Design

In real-time messages you still need:

Common practice:

Example WebSocket message:

json
{
  "type": "chat.message",
  "payload": {
    "id": 123,
    "room_id": 5,
    "text": "Hello",
    "author": "alice",
    "created_at": "2026-08-28T10:00:00Z"
  }
}

On the server:

On the client:

Versioning:

json
{
  "version": 1,
  "type": "chat.message",
  "payload": { ... }
}

When you change the message format later, you can handle old and new versions in parallel.

Security Considerations in Real-Time Apps

Security rules from standard APIs still apply, but there are extra considerations.

Important real-time security rules:

  • Always authenticate connections before accepting messages.
  • Never trust messages from clients without validation.
  • Treat every message like an API request with its own authorization checks.

Key points:

Putting It All Together

Real-time applications extend your backend beyond simple request-response. They let you:

The core patterns are:

  1. Choose the right technique (polling, long polling, SSE, WebSockets).
  2. Combine real-time connections with REST APIs and databases.
  3. Use message brokers for scale and distribution.
  4. Handle disconnections, reconnections, and missing messages.
  5. Use authentication, authorization, and validation on every live connection.

As a backend developer, you do not need to implement everything from scratch. Frameworks, libraries, and managed services can handle much of the low-level work. Your focus is on designing clear protocols, secure flows, and robust data handling so that your real-time features stay correct and reliable as your system grows.

Views: 9

Comments

Please login to add a comment.

Don't have an account? Register now!