Bird
Raised Fist0

Design Slack - Workspaces, Channels, Real-Time Delivery at Scale, Search

HLDhardInterview freq: high
Choose your preparation mode4 modes available
🎯
Design Slack - Workspaces, Channels, Real-Time Delivery at Scale, Search
45 min · senior
senior

Design a Slack-like messaging platform supporting 50 million daily active users (DAU), enabling multiple workspaces and channels per user, with real-time message delivery, offline message sync, and full-text search. The system must guarantee end-to-end encryption, deliver messages with P99 latency under 200ms, and support offline message delivery with eventual consistency.

  • End-to-end encryption for all messages and metadata
  • Support offline message delivery and sync upon reconnection
  • P99 message delivery latency under 200ms at 50M DAU
  • Support multi-tenant workspaces and channel membership management
  • Full-text search across messages with near real-time indexing
📋
Guided Steps
1/5
Step 1
Data Modeling for Workspaces, Channels, and Messages
How would you model workspaces, channels, and messages to support efficient queries and scalability?
💡 Hint
Consider partition keys that enable efficient range scans and membership queries.
Use Cassandra with partition_key=workspace_id for workspaces and partition_key=channel_id for messages - LSM-tree writes scale linearly, and range queries enable cursor-based sync per channel.
Mid: Names Cassandra for message storage. Senior: Explains why partitioning by channel_id ensures ordered writes and efficient range scans, and rejects sender_id partitioning due to out-of-order delivery and cross-partition reads.
⚠️Common Wrong Answer
Using a relational database with sender_id as partition key - causes hotspots and inefficient queries for channel-wide message retrieval.
Step 2
Real-Time Message Delivery Architecture
How would you design the real-time message delivery system to meet P99 latency < 200ms at 50M DAU?
💡 Hint
Think about partitioning, message ordering, and push mechanisms to clients.
Use Apache Kafka with partition_key=channel_id to ensure ordered message streams per channel; delivery workers consume from Kafka partitions and push via WebSocket connections managed by a scalable gateway layer (e.g., Envoy).
Mid: Names Kafka and WebSocket for delivery. Senior: Explains Kafka partitioning by channel_id to guarantee ordering and locality, and why HTTP polling is rejected due to excessive reconnect load at scale.
⚠️Common Wrong Answer
Using HTTP polling for real-time delivery - leads to 50M reconnects per minute, overwhelming backend and increasing latency.
Step 3
Offline Message Sync and Delivery Guarantees
How would you enable offline message delivery and efficient sync when clients reconnect?
💡 Hint
Consider cursor-based sync and durable storage for missed messages.
Implement cursor-based sync using Cassandra range queries on channel_id and message timestamp; clients send last received message ID to fetch missed messages; Redis stores ephemeral delivery state and presence for efficient routing.
Mid: Describes cursor-based sync with Cassandra. Senior: Explains Redis TTL-based presence tracking to avoid unnecessary delivery attempts and how cursor sync avoids duplicate messages and reduces bandwidth.
⚠️Common Wrong Answer
Relying on client-side full message reload on reconnect - causes high bandwidth usage and poor user experience.
Step 4
Full-Text Search over Messages
How would you design full-text search over messages with near real-time indexing?
💡 Hint
Separate search indexing from primary message storage and consider eventual consistency.
Use Elasticsearch for indexing messages asynchronously via Kafka Connect; messages are indexed with workspace_id and channel_id fields to support scoped search; eventual consistency accepted for indexing latency.
Mid: Names Elasticsearch for search. Senior: Explains asynchronous indexing via Kafka Connect to decouple search from write path and why synchronous indexing would increase write latency.
⚠️Common Wrong Answer
Using Cassandra secondary indexes for search - leads to poor performance and limited query capabilities.
Step 5
Security and End-to-End Encryption
How would you implement end-to-end encryption ensuring message confidentiality and metadata protection?
💡 Hint
Consider client-side encryption and key management separate from message transport.
Implement client-side encryption with keys managed per workspace and channel; messages encrypted before sending to Kafka and stored encrypted in Cassandra; server only routes encrypted blobs without access to plaintext.
Mid: Mentions encryption at rest and in transit. Senior: Details client-side encryption with key rotation and zero-knowledge server design, explaining trade-offs in search and delivery.
⚠️Common Wrong Answer
Encrypting only at rest on server - exposes plaintext to server operators and violates end-to-end encryption guarantees.
🔌
API Design Challenge
Sketch 3 core API endpoints for Slack: sending a message, syncing messages after offline, and acknowledging message receipt.
  • How does the client send a message to a channel or user?
  • How does the client efficiently sync missed messages after reconnecting?
  • How does the client acknowledge message receipt to ensure delivery guarantees?
📊
Scoring Rubric
▼ Show
Must Have - 60%
  • Use Cassandra partitioned by channel_id for scalable message storage
  • Use Kafka partitioned by channel_id for ordered real-time delivery
  • Use WebSocket for push delivery to meet P99 < 200ms latency
  • Implement cursor-based sync for offline message delivery
  • Use Elasticsearch for full-text search with asynchronous indexing
  • Implement client-side end-to-end encryption
Good to Have - 30%
  • Use Redis TTL presence for efficient offline detection
  • Design multi-tenant data isolation with workspace_id scoping
  • Explain trade-offs of synchronous vs asynchronous search indexing
Bonus - 10%
  • Discuss key rotation and zero-knowledge server design for encryption
  • Describe failure modes in Kafka partition rebalancing and mitigation
  • Explain scaling WebSocket gateways with Envoy or similar proxies
HTTP polling for real-time delivery at 50M DAU: 50M reconnects per minute just to check for messages - collapses under load
Using sender_id as Kafka partition key breaks message ordering and causes cross-partition reads, leading to inconsistent delivery
Synchronous search indexing in write path increases write latency and reduces throughput, impacting user experience
Storing plaintext messages on server exposes sensitive data to server operators and violates end-to-end encryption guarantees
✅
Model Answer
▼ Reveal

This design outlines a scalable Slack-like messaging platform supporting 50M DAU with real-time delivery, offline sync, full-text search, and end-to-end encryption. It leverages Cassandra for message storage partitioned by channel_id to enable ordered writes and efficient range queries. Apache Kafka streams messages partitioned by channel_id to guarantee ordering and scalability. WebSocket gateways (e.g., Envoy) provide low-latency push delivery. Redis tracks presence with TTL for efficient offline detection. Elasticsearch indexes messages asynchronously via Kafka Connect for near real-time search. Client-side encryption ensures message confidentiality with per-workspace/channel keys. Cursor-based sync protocols avoid duplicate message delivery and reduce bandwidth. Multi-tenant data isolation is enforced via workspace_id scoping across storage and indexing layers.

  • Partition Cassandra messages by channel_id to enable ordered writes and efficient range scans for cursor-based sync
  • Use Kafka partitioned by channel_id to guarantee ordered real-time message streaming and scalable consumption
  • Employ WebSocket gateways for low-latency push delivery to meet P99 latency under 200ms
  • Implement cursor-based sync using message IDs and timestamps to efficiently fetch missed messages after offline periods
  • Index messages asynchronously in Elasticsearch via Kafka Connect to decouple search indexing from write path and reduce write latency
  • Use Redis with TTL-based presence tracking to avoid unnecessary delivery attempts and optimize routing
  • Enforce client-side end-to-end encryption with per-workspace/channel keys to protect message confidentiality and metadata
  • Design multi-tenant data isolation by scoping all storage and indexing layers with workspace_id
  • Cassandra with partition_key=channel_id for message storage - enables ordered writes and efficient range scans for sync
  • Kafka with partition_key=channel_id for real-time ordered message streaming and delivery workers
  • WebSocket gateways (e.g., Envoy) for low-latency push delivery to clients
  • Redis with TTL-based presence tracking for efficient offline detection and delivery routing
  • Elasticsearch asynchronously indexing messages via Kafka Connect for near real-time full-text search
  • Client-side end-to-end encryption with per-workspace/channel keys to protect message confidentiality
  • Cursor-based sync protocol using message IDs and timestamps to avoid duplicate message delivery
  • Multi-tenant data isolation via workspace_id scoping in all storage and indexing layers

Practice

(1/5)
1. In the request flow, at Step 4 the Context Manager retrieves the conversation history before invoking the LLM. What happens if the context window exceeds the maximum token limit at this step?
easy
A. The Context Manager truncates the oldest messages to fit the token limit before sending to the LLM
B. The Context Manager sends the entire conversation history, causing the LLM to reject the request
C. The Context Manager splits the conversation into multiple requests to the LLM in parallel
D. The Context Manager caches the full history and waits for manual intervention

Solution

  1. Step 1: Understand Context Manager role at Step 4

    It must prepare input within the LLM's token window limit to avoid rejection.
  2. Step 2: Analyze behavior on exceeding token limit

    Sending full history (B) causes LLM errors; splitting requests (C) breaks context continuity; caching and manual intervention (D) is impractical. Truncation (A) preserves recent context within limits.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Context Manager truncates oldest messages to fit token window [check]
Hint: Truncate oldest context to fit token window, not entire history [check]
Common Mistakes:
2. In the faceted search request flow, at Step 4 the Query Coordinator merges partial results from multiple shard nodes. What happens if one shard node responds with a partial result missing some facet counts due to a timeout?
easy
A. The Query Coordinator excludes the shard's data entirely from the final result
B. The Query Coordinator merges available partial results and marks missing facets as zero counts
C. The Query Coordinator returns an error to the user immediately
D. The Query Coordinator retries the shard query synchronously before merging

Solution

  1. Step 1: Understand Query Coordinator's merge logic

    The coordinator merges partial results from all shards; if a shard times out, its data is excluded to avoid blocking the entire query.
  2. Step 2: Eliminate other options

    Returning an error breaks availability; marking missing facets as zero is inaccurate; synchronous retries would increase latency.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Timeout shard data excluded -> partial but available results [check]
Hint: Timeout shards excluded to keep query latency low [check]
Common Mistakes:
3. Without the DAU Estimator component, what exactly breaks in the system's capacity planning process?
medium
A. Bandwidth estimation fails because DAU directly affects total data transfer calculations
B. The system cannot estimate peak QPS, causing under-provisioning of servers
C. Storage estimation becomes inaccurate because DAU is a key multiplier for daily data volume
D. User authentication fails because DAU tracks active sessions

Solution

  1. Step 1: Identify DAU Estimator role

    DAU Estimator provides daily active user count critical for bandwidth calculations as bandwidth depends on total active users.
  2. Step 2: Eliminate other options

    The system cannot estimate peak QPS, causing under-provisioning of servers is incorrect because peak QPS depends on instantaneous requests, not just DAU; Storage estimation becomes inaccurate because DAU is a key multiplier for daily data volume is partially true but storage depends more on total objects, not DAU alone; User authentication fails because DAU tracks active sessions is unrelated to authentication.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Bandwidth depends directly on DAU for total data transfer [check]
Hint: Bandwidth depends directly on DAU count [check]
Common Mistakes:
4. For a real-time multiplayer game backend requiring low latency and consistent player state, which architecture is more appropriate and why?
medium
A. Stateful servers storing player state only in a distributed cache without persistence
B. Stateless microservices with external database for player state
C. Stateless servers with client-side state management and server validation
D. Stateful game servers maintaining player state in memory with periodic persistence

Solution

  1. Step 1: Analyze latency and consistency needs

    Real-time games require fast access to player state with strong consistency.
  2. Step 2: Evaluate architecture trade-offs

    Stateful servers with in-memory state reduce latency and allow immediate state updates; periodic persistence balances durability.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Stateful in-memory state + persistence -> low latency, consistent [check]
Hint: In-memory stateful servers best for real-time consistency [check]
Common Mistakes:
5. At 10x scale, which component in a BM25-based search ranking system is most likely to become the bottleneck first and why?
hard
A. The query parser, because it must handle exponentially more complex queries
B. The inverted index storage, because random disk seeks increase linearly with index size
C. The document frequency updater, because maintaining accurate DF counts requires global coordination
D. The ranking component, because BM25 scoring requires expensive per-document computations that grow with candidate set size

Solution

  1. Step 1: Analyze scaling impact on components

    Query parser scales well with parallelism; DF updater can be sharded; ranking scales with candidate pruning.
  2. Step 2: Identify inverted index storage bottleneck

    Inverted index storage faces increased random disk seeks as index grows, causing latency spikes; disk I/O is harder to scale linearly than CPU or memory.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Disk I/O random seeks in inverted index storage bottleneck first [check]
Hint: Disk random seeks in inverted index grow fastest at scale [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard