Ephemeral State Design
Typing state is intentionally ephemeral — stored only in Redis, never persisted to the database. There is no value in querying who was typing yesterday.
Redis Key Structure
Key: typing:{conversation_id}:{user_id}
Value: 1
TTL: 5 seconds
Redis keyspace notifications are enabled. When a key expires, a stopped-typing event is triggered, allowing the system to broadcast that the user stopped typing without any explicit client action.
Typing Start Flow
Client sends typing_start event
-> Server: SETEX typing:{conv_id}:{user_id} 5 1
-> Server publishes typing event to Redis pub/sub channel chat:{conv_id}
-> WebSocket nodes push typing event to all connected participants (excluding sender)
Typing Stop Flow
Client sends typing_stop event OR Redis TTL expires
-> Server publishes stopped event to chat:{conv_id}
-> WebSocket nodes push stopped event to participants
Debounce Strategy
- Client sends
typing_startevery 3 seconds while the user is actively typing. - Server-side TTL is 5 seconds — longer than the client interval.
- If the client disconnects abruptly, the key expires in at most 5 seconds, cleaning up state automatically.
Broadcast via Redis Pub/Sub
PUBLISH chat:{conversation_id} {"type":"typing","user_id":123}
All WebSocket nodes subscribed to that channel receive the event and forward it to clients in that conversation. The sender is excluded from delivery.
Participants List
Participants for a given conversation are read from the ConversationMember table (cached in Redis). Only members receive typing events.
Group Chat Display
To show "Alice and Bob are typing…", the client aggregates active typers received from the server. The server can also provide a batch query:
KEYS typing:{conv_id}:* -- scan active typers in a conversation
-> returns list of user_ids currently typing
Rate Limiting
Maximum 1 typing_start event per user per 2 seconds is enforced server-side to prevent event spam from misbehaving clients.
State Recovery on Reconnect
When a WebSocket client reconnects, it queries active typers in the current conversation:
SCAN typing:{conv_id}:*
-> returns all user_ids with active typing keys
This restores the typing indicator UI without waiting for new events.
Architecture Summary
Client --typing_start--> WS Node --SETEX + PUBLISH--> Redis
|
Other WS Nodes (subscribed)
|
Push to participants
See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering
See also: Atlassian Interview Guide