Skip to content

Multi-device sync

Copy page

Multi-device sync is scoped bucket convergence — not full-database replication.

  1. Authenticate each device with the same user (or shared shop membership)
  2. Resolve buckets from sync-rule parameters (membership table or JWT claims)
  3. Each device calls bucketsForSyncRule with the buckets it cares about
  4. All devices pull/push against the same server Postgres
LayerWebReact Native
PersistencewaSqlitePersistenceopSqlitePersistence
HTTPfetchinstallNitroFetch / createNizhalNitroClient
RealtimePartySocket defaultnitroWebSocketSource
Online detectionnavigator.onLinereactNativeOnlineDetector (NetInfo)

Use the same syncRules and mutators on server; generated contract types on both clients.

  • Local write < 50ms with network down (TanStack optimistic path)
  • After reconnect, remote device sees changes in < 5s with realtime (ping → pull)
  • Without realtime, pull.intervalMs or manual echo.pull() still converges

When the server assigns a different PK than the client’s optimistic ID, push ack returns the mapping. Collections rebase local rows via TanStack DB.

  • apps/credit-ledger/examples/multi-device-host.ts — scripted two-client check
  • apps/emulation chaos harness — N clients with partition/restart injectors
  • apps/op-sqlite-probe — real device persistence smoke

Removing a device user’s membership must shrink their buckets. Verify pull returns removedBuckets and local purge — not just 403 on push.