C.W.K.
Stream
Lesson 02 of 05 · published

Local-First Outbox

~12 min · local-first, outbox, offline, state-machine

Level 0Unmarked Path
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"The save happens on your phone. The network is a courier you can fire and rehire — it is never the thing that decides whether your thought survives."

The Save Is Local

Here is the invariant that makes field capture trustworthy: a breadcrumb commits locally, on the device, before any network sync is attempted. The moment you tap save, the thought is durable in a local outbox — and only then does the engine try to push it to Office. This means a dead hotel network, airplane mode, or an unreachable Pippa can never cost you a memory. Neither the Office connection nor Pippa is ever on the critical save path. The network's job is to deliver what is already safely saved, not to be the thing that saves it.

The Outbox State Machine

Each captured breadcrumb moves through an explicit set of states: LOCAL_ONLY, QUEUED, SYNCING, SYNCED, and FAILED_NEEDS_ATTENTION. The crucial rule is that the local payload is never deleted before an idempotent server acknowledgement. A crumb that failed to sync does not vanish and does not silently retry into a duplicate — it sits in a visible failed state until it is resolved. And because the stream always surfaces an unsynced count, you can see at a glance that your PWA storage is a staging area, not the final archive. Nothing is quietly dropped; nothing is quietly duplicated.

Why Idempotency Matters in the Field

Field networks are not just slow — they are ambiguous. A request goes out, the connection dies, and you genuinely do not know whether the server received it. The naive fix, blind retry, produces duplicates: two copies of the same crumb because the first one actually landed. Waystone gives each crumb a stable device-generated identity, so a retry is idempotent — the server recognizes it as the same crumb and does not create a second. This is the difference between an outbox that heals after a bad connection and one that quietly multiplies your memories every time the signal drops.

Local-first is not a performance trick; it is a trust guarantee. When the save is local and the sync is idempotent, the worst a bad network can do is delay your crumb — never lose it and never duplicate it. For a memory engine used in exactly the places networks fail, that guarantee is the product.

Code

The outbox lifecycle·text
tap save
   |
   v
LOCAL_ONLY  --queue-->  QUEUED  --push-->  SYNCING
   ^                                          |  |
   |                                   (ack)  |  |  (error)
   |                                          v  v
   |                                     SYNCED  FAILED_NEEDS_ATTENTION
   |                                                    |
   '------------------- retry (idempotent) ------------'

# The local payload is NEVER deleted before an idempotent ack.
# Stable crumb id => retry can't duplicate.
# The stream shows the unsynced count: staging area, not archive.

External links

Exercise

Test an app you rely on for quick capture: turn on airplane mode, save something, then check what happens. Did it save locally and sync later, or did it fail, spin, or lose your input? Now reconnect and watch for duplicates. An app that can't save offline, or that duplicates on reconnect, would fail you exactly where a travel tool is used most.
Hint
Two tests, both in airplane mode: (1) does the save survive with no network at all? (2) on reconnect, do you get one copy or two? Passing both means local-first plus idempotent sync. Failing either means the network is on your critical save path — the wrong place for it.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.