Low Level Design: Cursor Sharing Service

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: Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence

See also: Atlassian Interview Guide

See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering

Scroll to Top