Skip to content
Devgo

WhatsApp

High-concurrency chat with Erlang and per-group state

WhatsApp serves billions of users with a small engineering team using Erlang/BEAM, whose lightweight processes map naturally to per-user/per-group message passing. Messages are delivered via a persistent connection; offline messages are stored and pushed on reconnect.

Product constraints

  • Huge concurrent connections per server (BEAM excels here).
  • Messages must be delivered in order within a chat.
  • Offline delivery: store messages, push on reconnect.
  • End-to-end encryption; servers don't read message content.

High-level diagram

WhatsApp architectureA block diagram of the WhatsApp system's main components and request flow.SenderBEAM gatewayMessage logper chatFan-outRecipientOffline queue
Illustrative block diagram of WhatsApp. Not to scale; see the request path below for flow.

Request path

  1. Send. Sender's client sends the message over a persistent connection to their server; the server routes to the recipient's server/group.
  2. Route. For a group, the server fans out to each member's connection (or stores for offline members).
  3. Deliver/store. Online members get the message pushed; offline members have it queued and delivered on reconnect.
  4. Ack. Delivery/read receipts flow back; the message is retained until acknowledged, then eligible for deletion.

Data model

Per-chat message (ordered, append-only) keyed by chat id. Offline message queues per user. Minimal metadata (who, when, not content) for routing; content is end-to-end encrypted.

Storage / cache / queue choices

Storage

Append-only message per chat; offline queues per user.

Cache

In-memory per-connection/per-chat state in BEAM processes.

Queue

BEAM message passing is the queue; offline messages persist in a store.

Scaling levers

  • BEAM lightweight processes map to chats/users, enabling millions of concurrent connections per node.
  • Per-chat state in a process avoids shared-state contention.
  • Store-and-forward for offline users; deliver on reconnect.
  • Keep servers stateless of content (E2EE) to minimize trust surface.

Copy vs skip (for a smaller team)

Copy
  • Persistent connections with per-chat state.
  • Store-and-forward for offline delivery.
  • Append-only message logs per chat.
  • Minimize server-side content trust (E2EE).
Skip
  • Erlang/BEAM specifically (use any actor-model or per-connection state) unless you have Erlang expertise.
  • Per-message DB writes on the hot path (batch/persist async).
  • Centralized routing for all chats (shard by chat id).

, , , ,

Sources