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.
| Store | Cold feed, 10,000 posts | Feed across 100 circles | 20 writers at once | Remove a member of 500 | History of one item |
|---|---|---|---|---|---|
| Loess | 14 / 70 kB | 13 / 1.4 MB | 7.21 s | 3.44 s | 10 / 37 kB |
| Jazz 1 (jazz-tools 0.20.19) | 5 / 957 kB | 5 / 2.8 MB | 0.76 s | 2.42 s | 4 / 25 kB |
| Jazz 2 (jazz-tools 2.0.0-alpha.60) | 3 / 13 kB | 3 / 39 kB | 0.12 s | 0.05 s | 3 / 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.
| Store | How it works | Where it stops against the goals |
|---|---|---|
| Jazz 1 | Sealed 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. |
| Evolu | SQLite 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. |
| Syncular | SQLite on the device, with a sync server. | A cold view syncs the whole circle. No members or sealing. |
| LiveStore | An 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
| Tool | What it is | What Loess takes |
|---|---|---|
| Graft | Lazy, partial replication of SQLite pages to object storage. | The closest design. Graft needs its own metadata server and has no sealing. |
| sql.js-httpvfs | Read-only SQLite over HTTP range reads. | Proof that lazy B-tree reads work in a browser. |
| LiteFS, mvsqlite | SQLite 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).