Design Chat APIs, Storage, and Message Flows
DatabricksSoftware Engineer · OnsiteLast updated
Design chat APIs and database tables with durable message sends, idempotent retries, ordered history, live delivery, and reconnect recovery.
Design a basic chat system, concentrating on its APIs, database model, and the main user flows. Explain how a user sends a message, how other participants receive it, and how a reconnecting client retrieves messages it missed.
Constraints & Assumptions
- Begin with authenticated users and durable text messages in conversations. Clarify whether conversations are one-to-one, group-based, or both.
- Define a successful send in terms of durable storage. Keep delivery to a device and reading by a user as separate concepts.
- Include message history and reconnect behavior. Media attachments, end-to-end encryption, search, and very large deployment scale are optional extensions requiring further requirements.
- No traffic target or latency SLA is supplied. Focus on a coherent baseline rather than invented capacity figures.
Clarifying Questions to Ask
- Can membership change, and should new members see earlier messages?
- Is ordering required within each conversation, and what should retries do after a send times out?
- Does the product need delivered and read receipts, or only durable sends and history?
- Must live events reach every device signed in as the same user?
Part 1 — API contract
Define APIs for creating or joining the supported conversation type, sending a message, and retrieving history. Describe authentication, membership checks, pagination, and retry behavior.
What This Part Should Cover
- Conversation and message identifiers with explicit ownership and authorization rules.
- A client-generated idempotency key for a retried send.
- Stable history pagination and a boundary between storage acknowledgement and live delivery.
Part 2 — Database model
Define the tables or collections, primary keys, useful indexes, and transaction boundaries needed to support the APIs.
What This Part Should Cover
- Users, conversations, membership, and messages, with relationships that support access checks.
- A per-conversation ordering mechanism and an index that serves history retrieval.
- Uniqueness enforcement for retried sends and consistent message/outbox writes if asynchronous fanout is used.
Part 3 — Basic flows and failures
Walk through a successful send to an online recipient, a recipient who is offline, and a reconnect after a live connection is interrupted.
What This Part Should Cover
- The sequence of authorization, durable commit, acknowledgement, and notification.
- How missed or duplicated live events are reconciled with stored message history.
- How a timeout after commit is resolved without creating a second message.
Hints
Hint 1
Follow one message across boundaries: A message can be committed even if its acknowledgement or live notification is lost. Give the client a way to recover its identity and position in history.
Follow-up questions
- How would adding read receipts change the stored state and API?
- Where would membership removal be enforced for an already-connected client?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.