100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

How Would You Design Slack?

Learn how to design a Slack-like messaging system: channel logs, WebSocket fanout, presence, and offline catch-up.

hardQ55 of 224 in System Design Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

Design Slack as a set of channel-partitioned messaging services backed by persistent WebSocket (or long-poll fallback) connections, a fanout write path that appends messages to a per-channel log and pushes them to online members, and a durable store that lets offline members replay history on reconnect.

A client opens a persistent connection to a gateway that authenticates it and subscribes it to the workspace’s active channels. When a user sends a message, the API server writes it to a per-channel append-only log (partitioned by channel or workspace ID for horizontal scale), assigns it a monotonically increasing sequence number, and publishes it to a fanout service. The fanout service looks up which members are currently connected via a presence/connection registry and pushes the message directly to their gateway connections, while also writing an unread-cursor update for offline members so they can fetch missed messages by sequence number on reconnect. Search, file attachments, and threads are handled by separate services (a search index, blob storage with signed URLs, and a thread-reply table keyed by parent message ID) so the hot messaging path stays lean. Multi-workspace tenancy is handled by sharding storage and connection routing by workspace ID, and presence is tracked via lightweight heartbeats with a short TTL so stale connections are pruned quickly.

  • Persistent connections plus sequence numbers give exactly-once-in-order delivery to online clients and reliable catch-up for offline ones
  • Partitioning the message log by channel/workspace lets the write path scale horizontally without cross-channel coordination
  • Separating search, files, and threads from the hot send path keeps message latency low under load
  • A presence registry with heartbeats lets fanout skip offline members cheaply and route reconnect catch-up correctly

AI Mentor Explanation

Designing Slack is like running a stadium public-address system where every stand (channel) has its own numbered announcement feed instead of one shared microphone for the whole ground. A new announcement gets a sequence number and is pushed instantly to fans currently in their seats (online clients), while fans who stepped out can check the scoreboard replay (sequence-based catch-up) to see everything they missed in order. Separate staff handle photo replays and archived footage (files and search) so the live PA feed never stutters. This numbered, per-stand broadcast with a replay log is exactly how Slack fans out messages per channel.

Step-by-Step Explanation

  1. Step 1

    Establish persistent connection

    Client authenticates and opens a WebSocket to a gateway server, subscribing to its workspace channels.

  2. Step 2

    Append message to channel log

    API server writes the message to a per-channel partitioned log and assigns a monotonic sequence number.

  3. Step 3

    Fanout to online members

    The fanout service checks the presence registry and pushes the message over open connections to online members.

  4. Step 4

    Catch-up for offline members

    Offline clients reconnect and fetch messages after their last-seen sequence number to replay what they missed.

What Interviewer Expects

  • Explains persistent connections (WebSocket) plus a fallback and why polling alone would not scale
  • Describes partitioning the message log by channel/workspace for horizontal write scale
  • Uses sequence numbers or cursors for reliable ordering and offline catch-up
  • Separates hot-path messaging from search, files, and threads as distinct services

Common Mistakes

  • Proposing a single global broadcast to all clients instead of per-channel fanout
  • Forgetting how offline or reconnecting clients recover missed messages
  • Putting file storage and search on the same hot write path as messages
  • Ignoring presence tracking and treating every connection as always-online

Best Answer (HR Friendly)

I would build Slack around channels that each keep their own ordered message log, with a live connection pushing new messages instantly to people currently online. For anyone who is offline, we would let their app catch up by asking for everything after the last message they saw, so nothing gets lost and history stays consistent across devices.

Code Example

Fanout on message send (pseudo-code)
async function sendMessage(channelId, userId, body) {
  const seq = await channelLog.append(channelId, { userId, body, ts: Date.now() })

  const members = await presence.getOnlineMembers(channelId)
  for (const member of members) {
    const conn = connectionRegistry.get(member.userId)
    if (conn) conn.push({ channelId, seq, userId, body })
  }

  await unreadCursors.markPending(channelId, seq)
  return seq
}

async function catchUp(channelId, userId, lastSeenSeq) {
  return channelLog.readAfter(channelId, lastSeenSeq)
}

Follow-up Questions

  • How would you shard the message log so a single busy channel does not become a bottleneck?
  • How do you guarantee message ordering when a user is connected to multiple gateway servers over time?
  • How would you design threaded replies without duplicating the main channel log?
  • How would you scale presence tracking across millions of concurrent connections?

MCQ Practice

1. Why does Slack-style messaging assign a monotonic sequence number per channel?

Sequence numbers give clients a reliable cursor to request everything they missed in the correct order.

2. Why keep file storage and search out of the hot message-send path?

Isolating slower, heavier concerns from the fast messaging path keeps typical send latency low and lets each subsystem scale on its own.

3. What is the primary role of the presence registry in this design?

The presence registry lets the fanout service know who is online right now, so it can push live instead of relying on polling.

Flash Cards

How does Slack deliver messages to online users?A fanout service pushes new messages over persistent connections to members currently online in that channel.

How do offline users catch up?They request all messages after their last-seen sequence number when they reconnect.

Why partition the message log by channel?To scale writes horizontally without needing cross-channel coordination.

Why isolate search and files from messaging?To keep the hot send path fast while heavier features scale independently.

1 / 4

Continue Learning