Design Message Search

Medium45 min
1 / 30
understanding6 min read

Problem Statement & Context

How Problem Statement & Context shapes architecture and interviewer follow-ups for Design Message Search.

Design Message Search — product and retrieval context

Design full-text search across chat history for a Slack/Discord/WhatsApp-class product: users query keywords, phrases, filters (channel, author, date, attachments), and receive ranked hits with snippets within seconds—even when history spans billions of messages and strict access control applies per hit.

Why interviewers ask this

  • ACL at query time — every result must respect workspace membership, private channels, DMs, and legal hold without leaking metadata across tenants.
  • Write amplification — each message edit/delete triggers index maintenance; search is a read-heavy path fed by an async indexing pipeline.
  • E2EE tension — if message bodies are opaque on the server, you cannot run a classic centralized inverted index without a deliberate metadata or client-index strategy.

Scale anchors (stated assumptions)

SignalAssumption
DAU400M
Messages/day12B (~139k msg/s average)
Search queries80M/day (~930 QPS avg, 5× peak)
Index freshness SLAp95 < 5s from message commit
Query latency SLAp99 < 400ms for top-20 results

Architecture headline

Message Service commits durable records → outboxKafkaIndexer bulk-writes OpenSearch shards routed by workspace_id. Search API authenticates the user, expands visible conversation_ids from a membership cache, executes a filtered BM25 query, post-processes highlights, returns cursor pages.

javaOne Dark Pro
1public record SearchHit(String messageId, String conversationId, double score, String snippet) {}
pythonOne Dark Pro
1def acl_filter(conversation_ids: list[str]) -> dict:
2 return {"terms": {"conversation_id": conversation_ids}}
typescriptOne Dark Pro
1export interface SearchRequest {
2 query: string;
3 workspaceId: string;
4 filters?: { fromUserId?: string; before?: number };
5 cursor?: string;
6}

Why interviewers care

Message Search interviews reward crisp scope, explicit trade-offs, and failure stories—not generic microservice diagrams.

The failure that defines the design

The outage to narrate is the access-control leak: a search query returns a message from a conversation the user was never part of. Search systems are built to find everything fast, but private-message search must find only what the searcher is allowed to see — and if the ACL filter is bolted on after ranking, or the membership cache is stale after someone leaves a group, the index happily surfaces another person's messages. The fix is structural: ACL filtering is a mandatory, first-class part of every query, applied as a filter the index enforces, never a post-process. A message-search system lives or dies on never returning a result the user cannot legitimately see.

Key Highlights

  • Problem Statement & Context: decisive interview anchor
  • ACL enforced in coordinator DSL, never UI-only
  • Async indexing with versioned idempotent upserts
Interviewer signal
When discussing Problem Statement & Context, cite numeric assumptions and an ACL or indexing failure mode.
Avoid
Do not index before defining E2EE boundaries and tombstone policy.

Section Rescue Kit

Buzzwords to use:

ACL Filter Contextsearch_after Cursor

Safe statements:

  • "For Problem Statement & Context, I will quantify index lag and query p99 before picking shard counts."
  • "I never return search hits outside membership—cache miss fails closed."
Design Message Search - System Design | WinJob | WinJob