Zoop.One

Designing Real-Time Collaboration

How WebSockets, Redis and MongoDB worked together to support real-time document interactions.

The Problem

Real-time document collaboration requires multiple users to work on the same document while changes are happening continuously. Unlike normal request-response APIs, updates need to move between clients and the server instantly while shared state remains coordinated and changes are reliably persisted.

The Constraint

Bidirectional Communication

Clients and the server needed to send and receive updates continuously.

Real-Time Events

Document changes needed to propagate immediately as users interacted.

Shared State

Multiple connected clients needed to stay synchronized around the same document.

Persistence

Real-time changes still needed to be reliably stored as durable document data.

  • Bidirectional CommunicationClients and the server needed to send and receive updates continuously.
  • Real-Time EventsDocument changes needed to propagate immediately as users interacted.
  • Shared StateMultiple connected clients needed to stay synchronized around the same document.
  • PersistenceReal-time changes still needed to be reliably stored as durable document data.

The Options

Polling

Not Chosen

Server-Sent Updates

Not Chosen

WebSocket-Based Communication

Chosen

Why We Chose It

WebSockets keep a persistent two-way connection between clients and the server.

Benefit

Fast bidirectional communication for real-time collaboration.

Drawback

More connection, reconnection, and event coordination complexity.

Decision Rationale

Why We Chose The Approach

Real-time document collaboration architectureConnected clients exchange document events through a WebSocket server. Redis coordinates events and transient shared state. The server reads and saves durable documents in MongoDB. Select a node or its explanation to highlight the flow.WebSocket serverRedisEVENTS · SHARED STATEMongoDBDURABLE DOCUMENTS

The Result

Real-time updates stayed responsive while shared state and persistence remained separated.

In Retrospect

If I were building this again, I'd evaluate the same decision around three questions:

  1. How quickly is analytics volume growing?
  2. How much operational complexity does another datastore introduce?
  3. Can simpler aggregation solve the problem first?