Katkat

Design a Real-Time Shared To-Do List

RobloxSoftware Engineer · Technical Screen

Last updated

Design a real-time collaborative to-do list supporting concurrent edits, task reordering, fast write confirmations, and seamless reconnect recovery.

Scenario

Design the backend architecture for a real-time collaborative task list application (such as shared party checklists or team sprint boards). Multiple users can view, add, check off, edit, and reorder tasks within the same list concurrently. Edits must be durable, immediately acknowledged to the author, and propagated to other active collaborators with sub-second latency.

Requirements

Functional Requirements

  • Shared Lists: Users can create lists, invite collaborators, and view real-time changes.
  • Task Operations: Support creating, updating (title, status, assignee), deleting, and reordering tasks.
  • Real-Time Synchronization: Active collaborators on a list must see changes pushed to them in near real-time.
  • Durable Writes: A user modifying a task must receive an explicit, synchronous acknowledgement once the update is committed to persistent storage.
  • Conflict Resolution: Explicitly handle concurrent edits (e.g., two users modifying the same item simultaneously or reordering overlapping items).
  • Reconnect & Catch-up: Clients that temporarily lose connection must be able to catch up without re-downloading the entire list state.

Non-Functional Requirements

  • Scale: 10 million daily active users (DAU); 1 million concurrent active lists at peak.
  • Group Size: Typically 2–10 active users per list; up to 100 peak collaborators per list.
  • Latency: Write durability acknowledgement < 100ms; end-to-end fan-out latency to collaborators < 250ms.
  • Availability & Consistency: Authoritative state must maintain per-list linearizability or strong causal consistency; no silent data loss.

What Your Design Should Cover

  1. API & Data Model: Core data models, task ordering strategy (e.g., fractional indexing / LexoRank), and versioning mechanism.
  2. Architecture & Data Flow: Clear separation between the synchronous authoritative write path (HTTP/WebSocket to storage) and the asynchronous fan-out path (Pub/Sub to connected clients).
  3. Concurrency & Conflicts: Strategy for handling conflicting updates and concurrent reordering (e.g., optimistic concurrency control with monotonic version numbers).
  4. Connection Management & Catch-up: WebSocket connection tier, subscription tracking, and delta-based state synchronization upon client reconnection.

Hints

Hint 1

Keep the authoritative mutation path synchronous to persistent storage to return immediate success/failure acks; use message queues or pub/sub purely for downstream fan-out to other connected subscribers.

Hint 2

For concurrent task reordering, consider fractional indexing (floating point or LexoRank string keys) paired with version checks to avoid rewriting index positions across the entire list.

Hint 3

Assign a monotonically increasing sequence number per list mutation so reconnecting clients can fetch a compact delta log of events since their last observed sequence ID.

Follow-up questions

  • How does your architecture handle a sudden burst of 10,000 read-only viewers on a public shared list without overwhelming the database or WebSocket connections?
  • If two users edit the description of the same task while offline and then both reconnect, how would your system resolve or merge the conflict?
  • How would you implement log compaction or snapshotting for the per-list mutation history to prevent unbounded storage growth over years of edits?