Cursor State
{
user_id,
user_name,
color,
position: { line, col } // for text, or { x, y } for canvas
selection: { anchor, head },
last_updated
}
Ephemeral Storage (Redis)
Cursor state stored only in Redis, not DB.
HSET cursors:{doc_id} user_id {serialized_cursor_state}
EXPIRE cursors:{doc_id} 30s -- refreshed on each cursor move
Broadcast
Cursor move event → publish to Redis channel doc:{doc_id}:cursors → all WebSocket nodes push to connected clients.
Debounce: client sends cursor updates at most every 50ms.
Awareness Protocol
On join: client fetches all active cursors (HGETALL cursors:{doc_id}) and subscribes to channel.
On disconnect: remove user from hash (HDEL) → broadcast cursor-leave event.
Color Assignment
Deterministic color from hash of user_id (16 distinct colors).
UI Features
Selection
Highlight range in collaborator color.
Name Tag
Floating label near cursor showing user name.
Ghost Cursor
Show last known position faded when user is idle (no movement in 10s).
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “Where is cursor state stored in a cursor sharing service?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Cursor state is ephemeral and stored only in Redis using a hash keyed by cursors:{doc_id}. Each user's cursor entry has a 30-second TTL that refreshes on every cursor move, so stale cursors expire automatically.”
}
},
{
“@type”: “Question”,
“name”: “How are cursor updates broadcast to collaborators?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “A cursor move event is published to a Redis Pub/Sub channel (doc:{doc_id}:cursors). All WebSocket server nodes subscribed to that channel push the update to their connected clients. The client debounces cursor events to at most one per 50ms.”
}
},
{
“@type”: “Question”,
“name”: “How are collaborator cursor colors assigned?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Colors are assigned deterministically by hashing the user_id and mapping the result to one of 16 distinct colors. This ensures the same user always appears in the same color without needing to store the assignment.”
}
},
{
“@type”: “Question”,
“name”: “What happens to a cursor when a user disconnects or goes idle?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “On disconnect, the user's entry is removed from the Redis hash (HDEL) and a cursor-leave event is broadcast so other clients remove that cursor immediately. If the user is merely idle (no movement for 10 seconds), a ghost cursor shows the last known position in a faded style.”
}
}
]
}
See also: Atlassian Interview Guide
See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering