Skip to content

feat: Streaming initial sync for new realms (paginated sync) #2286

@liz709

Description

@liz709

Problem

Initial sync for users with large datasets (10k–20k+ objects) transfers and applies the entire dataset in a single atomic operation. This causes:

  • Memory pressure — 20–50 MB JSON response held in memory
  • Long-blocking transactions — 120k+ IndexedDB writes in one transaction, blocking UI
  • Poor UX — no progress feedback during what can be a multi-second operation
  • Resource limit crashes — e.g. Cloudflare Durable Objects (30s CPU limit) always fail for large datasets

This is a general UX issue for any Dexie Cloud user with a large initial dataset, not specific to any deployment environment.

Proposed Solution

Stream the initial download of new realms as NDJSON (outside the main ACID transaction), similar to how Y.js data is already handled via registerYDownloadEndpoint.ts.

Why new realms only (for now)?

  • No client changes to apply → no conflict resolution needed
  • Much simpler than paginating ongoing delta sync
  • Covers the primary pain point (cold start / first sync)

Consistency model (3 steps)

  1. Normal sync for existing realms → rev1
  2. Stream new realm(s) with read-isolated PG transaction → rev2
  3. If rev2 > rev1: re-run normal sync, but skip consistent-operations for newly downloaded realms to avoid double-applying mutations (e.g. @@propmod)

Local intermediate storage

Raw NDJSON buffered locally before atomic apply:

  • OPFS in modern browsers (fast, low overhead)
  • Dexie $realmDownload table as fallback (CF Workers, older browsers)

Progress reporting

Wire up the existing (currently no-op) progress prop in sync state to emit download progress during realm streaming.

Backward compatible

Opt-in via a flag in the sync request. Old clients/servers fall back to current behavior.

Existing foundations

  • StreamingSyncProcessor.ts in dexie-cloud-common — designed but unconnected streaming types and async generators
  • registerYDownloadEndpoint.ts — Y.js download already happens outside main transaction
  • Export/Import NDJSON streaming — battle-tested streaming infrastructure

Affected repos

  • dexie/Dexie.js (dexie-cloud-addon: sync loop, apply, progress)
  • dexie/dexie-cloud (server: new streaming endpoint for realm download)
  • dexie/dexie-cloud (dexie-cloud-common: protocol types)

References

  • Detailed design doc: internal docs/paginated-sync-design.md
  • Reported by Bennie Forss (ToToDo) — real production impact with 20k+ objects in CF Durable Objects
  • Design discussion: Discord #liz-lead-dev, 2026-03-28

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions