back to projects
shipped· 8 months

Syncwave

Realtime collaboration engine for design tools

TypeScriptBunRedisPostgresWebSocketY.js

Why I built this

Most realtime collaboration backends are coupled to a specific frontend. I wanted a runtime-agnostic engine that could be dropped into any product.

The problem

Concurrent editing requires conflict resolution, presence, and persistence — but most teams reinvent the wheel poorly. Latency and consistency tradeoffs are subtle.

target users: Small product teams shipping multiplayer features.

Core features

  • CRDT-based document sync (Y.js core)
  • Presence + cursor broadcasting
  • Server-side persistence with snapshot compaction
  • Horizontal scaling via Redis pub/sub
  • Pluggable auth + room access control

Technical challenges

  • Backpressure handling for slow clients without blocking the room
  • Snapshot compaction without breaking active sessions
  • Cross-node pub/sub message ordering at scale

Engineering decisions

Why Bun over Node

Bun's WebSocket implementation was ~2.3x faster in our benchmarks for small-frame fanout. We accepted ecosystem risk for the throughput.

Why Y.js over Automerge

Y.js had better memory characteristics for our workload (long-lived documents with many small edits). Automerge's history compaction was a research project we didn't want to own.

Lessons learned

  • WebSocket fanout is cheap; serialization is not. JSON encoding became the hot path until we moved to a binary protocol.
  • Redis pub/sub is fine until ~10k rooms per node. Beyond that, sharded streams win.
  • Optimistic UI hides a lot of sync bugs — always test with artificial latency.