Productivity & collaboration · Intermediate

Notion-like workspace

Block data model in workspace-sharded Postgres, optimistic transactions and record subscriptions.

Every part, and why it is there

Desktop, web & mobile

Edit pages made of blocks: text, to-dos, tables, embeds. Every edit appears locally in milliseconds and is saved in the background.

CDN

Uploaded images and files, plus the app’s own static assets.

File uploads (S3)

Attachments and images. Blocks only hold a reference.

Load balancer

Sends API calls to the app servers and WebSocket connections to the message store.

API servers

POST /saveTransactions receives a batch of block operations, loads the affected blocks, applies the operations, checks permissions by walking parent pointers up to the workspace, and commits them together or not at all. POST /loadPageChunk returns a page’s blocks in pieces.

Block store (sharded Postgres)

Every block (id, type, properties, ordered list of child ids, parent id) lives in one table, split into hundreds of logical shards by workspace id. Keeping a workspace together means a page load or permission check never crosses shards.

Block cache

Recently read blocks and their versions. Popular pages and templates are read far more than written.

Message store

Each client keeps a WebSocket open and subscribes to the records on screen. When a block changes, subscribers get “record X is now version 12” and fetch it if their copy is older.

Subscriptions

Which connections are watching which record. Lost on restart, which is fine: clients simply resubscribe.

Block change events (Kafka)

Every committed change, consumed by search indexing and the data lake. Keeps those slow jobs entirely out of the save path.

Search indexer

Updates full-text search from changed blocks.

Search index

Search across pages a user can access. Updated asynchronously, so a just-typed word may take a moment to be findable.

Lake ingestion

Copies block changes into the data lake for analytics and AI features, without running heavy queries against production Postgres.

Data lake

Columnar copies of all blocks for analytics, kept fresh within minutes.

Learn more

All system design examples