Skip to content
Loess

Comparisons

This doc compares how existing sync stores meet the goals, and where Loess differs.

Sync stores

The bench runs each store's servers on one machine behind the same simulated network, and its README says how it measures. A cell shows serial round trips and bytes downloaded, or the time at a 40 ms round trip where noted. The read scenarios include signing in on a new device.

StoreCold feed, 10,000 postsFeed across 100 circles20 writers at onceRemove a member of 500History of one item
Loess14 / 70 kB13 / 1.4 MB7.21 s3.44 s10 / 37 kB
Jazz 1 (jazz-tools 0.20.19)5 / 957 kB5 / 2.8 MB0.76 s2.42 s4 / 25 kB
Jazz 2 (jazz-tools 2.0.0-alpha.60)3 / 13 kB3 / 39 kB0.12 s0.05 s3 / 49 kB

Jazz 2 is a different store from Jazz 1 under the same package name. Its server reads every row, so it is under Stores that are out, and the table shows it for reference.

StoreHow it worksWhere it stops against the goals
Jazz 1Sealed collaborative values (CoValues), synced by a server that cannot read them.A new device loads a feed's whole list of references: 957 kB to show 20 posts of 10,000.
EvoluSQLite on the device. Rows sync sealed through a relay.A cold view syncs the whole owner's data and history. No shared groups with roles.
SyncularSQLite on the device, with a sync server.A cold view syncs the whole circle. No members or sealing.
LiveStoreAn event log, with SQLite on the device built from it.A cold view pulls the whole log. It does not seal events.

The bench doesn't run Evolu, Syncular, or LiveStore. Loess asks for a cold view that costs only what the view reads.

Prior art that is not a sync store

ToolWhat it isWhat Loess takes
GraftLazy, partial replication of SQLite pages to object storage.The closest design. Graft needs its own metadata server and has no sealing.
sql.js-httpvfsRead-only SQLite over HTTP range reads.Proof that lazy B-tree reads work in a browser.
LiteFS, mvsqliteSQLite with versioned pages and a central page index.Ideas for the page map.

Stores that are out

  • No encryption and no path to it: Zero, ElectricSQL, InstantDB, PowerSync, Jazz 2, and Triplit. The host reads the data (private).
  • SpacetimeDB. The host runs each app's server code, which reads every row to check access, and clients call that code instead of signing writes. Its client cache lives in memory, so an app can't open or write offline.
  • Peer-to-peer stores, such as Automerge with automerge-repo. No single place orders the writes of a shared circle, so there is no authoritative answer to who is a member (a non-goal).

Where Loess differs

  • A cold view fetches only the database pages that the view reads, so the cost grows with the view and not with the circle (offline).
  • Storage is a bucket behind a Worker that only gets objects and stores a head with a compare-and-swap. It cannot read data, and any bucket can be the storage (any host, private).
  • Any SQL query, full-text search, and history as a query, on the official SQLite build (shared facts).
  • The trade-off: a write counts only once a committer that the circle's owners list commits it, such as an owner's device or the host's committer service, which reads the circles it commits (architecture).