Real-Time Collaboration Systems
Asked of: Software Engineer
Last updated

What's being tested
This tests whether you can design a real-time distributed system that combines durable state, low-latency delivery, reconnect recovery, and authorization without confusing those responsibilities. You need to reason about ordering, idempotency, failure handling, and hot-spot scaling rather than treating WebSockets as the entire solution. Figma cares because collaborative documents and canvases require users to observe shared state quickly and consistently while edits, comments, disconnects, and permission changes happen concurrently.
Core knowledge
-
Separate the source of truth from delivery. Persist comment mutations in a durable store such as
Postgresor a partitioned document store; use WebSockets only for best-effort notification. A client must be able to recover entirely through reads and backfill. -
Model comments with stable identifiers:
comment_id,document_id,thread_id,author_id, body, timestamps, deletion state, and an ordering token. Generate IDs client- or server-side with collision-resistant UUIDs; never use arrival time alone as identity or ordering. -
Use idempotency keys for creates and mutations. Store
(actor_id, request_id)with the resulting operation so retries after timeouts return the original result instead of creating duplicate comments. -
Choose an ordering contract explicitly. A per-document monotonically increasing sequence such as
document_versiongives clients a resume cursor; wall-clock timestamps do not guarantee order because clocks skew and requests arrive through different servers. -
A typical write path is: authenticate, authorize against the document, validate, transact the mutation and sequence assignment, commit durably, then publish an event. Publishing before commit risks phantom events; publishing after commit risks delayed fanout, so consumers must tolerate retries.
-
Reconnect backfill should accept a cursor, such as “events after version 1842,” and return events plus a new cursor. Handle retention gaps with a snapshot or full comment read; never assume a disconnected client can replay an infinite event log.
-
WebSocket delivery is usually at-least-once. Include
event_idor sequence numbers, deduplicate on the client, acknowledge or track the last applied cursor, and make applying an event safe when it is received twice. -
Use a fanout service backed by
Redis,NATS, orKafkawhen multiple application servers may hold connections. Partition events bydocument_idwhen per-document ordering matters; consumers should reject, buffer, or recover from sequence gaps. -
Scale hot documents independently from ordinary documents. Shard connection management and fanout by document, cap subscriptions or event rates, batch notifications, and use snapshot-plus-delta delivery when a document has thousands of viewers or a large backlog.
-
Permissions must be checked at write time and considered during delivery. Do not rely only on connection-time authorization: membership can be revoked, comments may have restricted visibility, and queued events must be filtered or invalidated after access changes.
-
Define failure behavior for every boundary: database timeout, publish failure, stale WebSocket, duplicate request, server restart, and client reconnect. An outbox table or transactional outbox pattern can make committed mutations reliably discoverable by the fanout pipeline.
-
Distinguish comment semantics from canvas-edit semantics. Comments may tolerate serialized per-thread or per-document mutations, while rich-text or object edits may require CRDTs or operational transformation; do not introduce CRDT complexity unless concurrent mutation semantics require it.
Worked example: Design Real-Time Collaborative Comments
For Design Real-Time Collaborative Comments, I would first clarify expected scale, whether comments are document-scoped or thread-scoped, required ordering, offline support, edit/delete semantics, and whether every collaborator can see every comment. I would declare an assumption such as durable comments with near-real-time updates, per-document ordering, authenticated users, and recovery after arbitrary disconnects. I would organize the answer around the data model and write path, WebSocket connection and fanout architecture, cursor-based reconnect/backfill, and authorization plus operational failure handling. Each mutation would receive an idempotency key, commit a comment event and sequence number transactionally, and then become available to a fanout worker. Clients would apply events by sequence, ignore duplicates, and request a snapshot or replay when they detect a gap. The key tradeoff is whether to use a single ordered stream per document, which simplifies correctness but can bottleneck hot documents, or partition more aggressively, which improves scale but complicates ordering. I would explicitly state that WebSockets are not durable storage and that reconnect reads must work even if an event was never delivered. If I had more time, I would detail the transactional outbox schema, authorization revocation behavior, metrics such as p99 fanout latency and reconnect recovery rate, and load-test behavior for a single extremely hot document.
A second angle
The same design changes substantially when users can create, edit, resolve, and delete comments while offline and then reconnect with multiple pending operations. The server should still assign authoritative sequence numbers, but it must accept idempotent retries and return conflict outcomes rather than assuming the client’s local order is globally valid. A lightweight last-write-wins policy may work for comment metadata, while concurrent text edits may need an operation-based merge strategy or a CRDT. The important boundary remains the same: durable mutation processing determines truth, while the real-time channel accelerates propagation of that truth.
Common pitfalls
Pitfall: Treating WebSocket delivery as persistence. Saying “broadcast the comment to connected users” omits disconnected clients, server restarts, and missed messages; describe a durable write path plus cursor-based recovery.
Pitfall: Claiming timestamps provide ordering. A tempting answer sorts by
created_at, but clock skew and concurrent requests make that unreliable; use a documented per-document sequence or explain the weaker consistency contract.
Pitfall: Jumping immediately to CRDTs or
Kafkawithout defining guarantees. The interviewer needs to hear the required ordering, retry, authorization, and scale assumptions first, then the minimum mechanism that satisfies them.
Connections
An interviewer may pivot to CRDTs, operational transformation, transactional outboxes, event sourcing, or presence systems. They may also ask how authorization changes, multi-region writes, or backpressure affect the consistency and latency contract.
Further reading
-
Designing Data-Intensive Applications — Martin Kleppmann’s treatment of replication, logs, consistency, streams, and distributed-system failure modes.
-
Conflict-free Replicated Data Types — foundational paper on replicated data structures for concurrent offline-capable editing.
-
Real-time collaboration with operational transformation — practical background on concurrent editing and transformation-based conflict resolution.
Practice questions
Related concepts
- Adobe Real-Time Collaboration WebSockets
- Real-Time Messaging And Collaboration SystemsSystem Design
- Adobe Real-Time Collaboration And WebSockets
- Adobe Document Cloud real-time collaboration and offline sync
- Adobe Creative Cloud Real-Time Collaboration And Offline Sync
- Adobe Real-Time Collaboration Messaging