RSS Amplifier

System Design Interview Roadmap · Aug 4, 2026

Design Slack — Walkthrough

0
Sign in to vote or save

System Design Roadmap · System Design Interview Roadmap

Slack is WhatsApp + channels + threads + search.

The messaging core is identical to WhatsApp (WebSocket, Cassandra, delivery semantics). The probes unique to Slack: channel message fan-out (a channel with 10,000 members means one message = 10,000 deliveries), message threading (replies live in a separate namespace from channel messages), and full-text search over message history.

- Direct messages only, or channels + DMs + threads? (Scope to channels + DMs) - Search over message history? (Yes — search is a major Slack differentiator) - Max members per channel? (Slack allows ~10K for standard, unlimited for Enterprise Grid)

- File sharing? (Yes — same object storage pattern as WhatsApp media) - SLO: message delivery < 200ms p99 within same workspace

- 20M DAU × 200 messages/day = 4B messages/day = ~46K messages/sec - Average channel size: 50 members → fan-out 50 deliveries per message - Large channels (10K members): 1 message = 10K WebSocket pushes - Message retention: Slack keeps all history (unlimited on paid plans) → ~500 bytes/msg × 4B msgs/day × 365 days = ~730 TB/year

Get Access to GitHub Repo

WebSocket: wss://slack.com/connect (per workspace per device)

POST /v1/messages

Body: { channel_id, text, thread_ts (optional — reply), blocks[], files[] }

Idempotency-Key: header

Response: { ts (message timestamp, also its ID), channel_id }

GET /v1/channels/:channel_id/messages

Query: cursor, limit, oldest, latest (time range)

Response: { messages[], has_more, next_cursor }

POST /v1/search

Body: { query, channel_ids[], from_user, date_range }

Response: { messages: [{ts, channel_id, text, permalink}], total }

ts (timestamp) is Slack’s actual message ID — a Unix timestamp with microsecond precision, unique per channel.

- messages (Cassandra): PARTITION BY channel_id, CLUSTER BY ts DESC — identical pattern to WhatsApp but scoped to channel

- threads: thread_ts (FK to parent message ts), reply messages in same table with thread_ts as additional cluster key

- channel_members: channel_id, user_id, joined_at — indexed both ways (channel→members for fan-out, user→channels for sidebar)

- search_index (Elasticsearch): message ts, channel_id, text, user_id, timestamp — updated async via Kafka consumer

- unread_counts (Redis): user_id:channel_id → {unread_count, last_read_ts} — updated on every message and read event

Read the original on systemdr.systemdrd.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.