Problem statement
Design the typing-indicator bus for a chat product, the system behind the line that appears to the other people in a conversation while someone composes a message. The signal is purely ephemeral: it is never stored, it is fine to drop occasionally, and it must vanish on its own if the sender stops or disconnects.
Operating context. Typing events are extraordinarily high-volume and low-value individually: a single user generates a burst as they type, and every event must fan out to the other participants of that conversation in well under a second to feel live. Nothing is persisted, so a lost event just means a slightly stale indicator, which is acceptable. Indicators must auto-expire after a few seconds of no update so a crashed or backgrounded sender does not leave a stuck indicator forever. Group conversations fan a single typing event out to many recipients, and clients throttle how often they emit, but the server must still shed load gracefully under bursts.
Out of scope. Durable message delivery, presence and last-seen, read receipts, and any storage or history of typing activity. Assume you receive an authenticated typing event tagged with a sender and a conversation id, and that another service can tell you the current participants of a conversation.
What to produce. A high-level architecture covering: how typing events are ingested and routed to a conversation's online participants, how the fan-out is kept cheap given the volume and the throwaway nature of the data, how indicators auto-expire without a persistent timer per event, how you throttle or coalesce bursts, and how the system sheds load under pressure without affecting real message delivery. Sketch the components and the event flow; checkpoints will probe fan-out cost and auto-expiry.
Must do 5
Functional requirements
- Accept typing-start and typing-stop events for a sender in a given conversation.
- Fan a typing event out to the other currently-connected participants of that conversation.
- Auto-expire an indicator after a few seconds without a refresh from the sender.