Deployment guide

Choose a deployment shape for a Server SDK application by scale, from one machine to a separate import and export node and multiple collaboration nodes.

This page describes three deployment shapes for a Server SDK application by scale. Read Collaboration SDK, import and export, and the examples first to see how the modules are assembled; deployment places the same assembly on one or more nodes.

ShapeCollaborationImport and exportRecommended scale
Single machineOne nodeSame nodeLocal applications, development, a few internal users
Split import and exportOne nodeSeparate nodeMulti-user online service within one node's capacity
Multiple nodesSeveral nodesSeparate nodeBeyond one node's capacity, or node failover

Single machine

Everything runs in one Node.js process, and the browser connects to it directly.

100%
  • The Database Adapter implements the IDatabaseAdapter contract. See Database Adapters.
  • Task and file storage, timeouts, and download links for import and export are covered in File exchange integration.
  • A conversion is CPU-bound, and a large file slows collaboration.

Split import and export when conversions affect collaboration latency or the service must stay available to many users.

Split import and export

Import and export move to a separate node; collaboration stays one node; the gateway routes the two kinds of paths separately; both use the same database.

100%

The import and export node assembles the Database Adapter, a UniverCollabService, and the conversion module, and works straight from the database; the injection points are the same as on a single machine.

The documents a single collaboration node serves are bounded by process memory. Move to multiple nodes beyond that capacity or for failover.

Multiple collaboration nodes

Several collaboration nodes run the same code against the same database. A pub/sub adapter relays Rooms, Presence, and broadcasts between nodes, a ticket store shares Session Tickets, and @univerjs-pro/collaboration-cluster-redis provides the Redis implementation. Reference example: Multi-node.

100%

Every collaboration node passes the Redis pub/sub adapter and ticket store to the Endpoint; the rest of the assembly stays the same:

TypeScript
import { createClient } from "redis";import { RedisPubSubAdapter, RedisSessionTicketStore } from "@univerjs-pro/collaboration-cluster-redis";import { UniverCollabEndpoint } from "@univerjs-pro/collaboration-endpoint";const client = createClient({ url: process.env.REDIS_URL });const subClient = client.duplicate();await Promise.all([client.connect(), subClient.connect()]);const pubSub = new RedisPubSubAdapter({ pubClient: client, subClient });const ticketStore = new RedisSessionTicketStore({ client });const endpoint = new UniverCollabEndpoint(service, { pubSub, ticketStore });

Going further

A very large document slows the requests of the small documents on the same node. Partition node pools by document size and let the gateway route large documents to a dedicated pool; the routing key stays the unit ID, and every pool shares the database and pub/sub.

How is this guide?

© 2026 DreamNum Co., Ltd.