Offline sync on Cloudflare Durable Objects
Why one SQLite Durable Object per person suits offline-first sync, and how SyncPilled orders, settles and stores each person's changes.
A sync server has to settle changes from several devices of one person, in order, without losing any. Cloudflare's Durable Objects make that small: each person gets an object of their own, with its own SQLite database, and the object handles one request at a time.
One object per person
- No locks. Two devices pushing at once reach the same object, which applies their changes one after the other.
- No shared database ceiling. Each person's data is its own database of up to 10 GB, instead of everyone's in one table.
- Deletion is simple. Deleting a person's account wipes their object.
- Placement. An object lives in one Cloudflare location, and a deployment can hint where new ones are created.
What the object keeps
- Current records, each with the position of the change that made it, so a pull is "everything after position N".
- History, every change applied, for exports that want past versions.
- Ignored changes, so a resend of a change that lost loses again.
- Usage, running totals of the person's record and file bytes, for limits that refuse growth and never deletion.
Around it
A Worker checks each request's token and passes it to the person's object. D1 holds the list of apps and people, so exports and deletions can find every object; R2 holds files by content hash. SyncPilled is open source, so all of this is code you can read and run on your own account.