Notes — Engineering RFC RFC-0142

Offline-First Sync for Notes

Make the on-device database the source of truth and synchronize opportunistically, so every note stays readable and writable with or without a network connection.

Status
Draft — for review
Author
A. Okafor — Client Platform
Reviewers
M. Chen (Sync Infra) · R. Iyer (Mobile) · T. Laurent (Security)
Created
Sep 15, 2026 · rev 0.3
Target release
Notes 4.2 (Oct train)
Related
RFC-0097 E2EE key rotation · DES-0211 conflict UI

1Summary

Notes today requires connectivity to read or write. We propose a local-first architecture: the device database is authoritative, a background engine reconciles with the server, and E2EE is preserved. Ships behind a kill-switch flag.

2Motivation

Offline or degraded-network sessions account for 31% of mobile opens but produce 72% of “lost note” support reports (Q2 review). A failed save retries in memory; force-quitting discards the edit. Offline access is the most-cited complaint in store reviews.

3Goals & Non-Goals

Goals
  • Reads and writes never block on the network.
  • Multi-device edits merge unattended in ≥99% of cases.
  • E2EE preserved — the server stores ciphertext ops only.
  • Sync lag <5s p50; durable across crashes.
Non-goals
  • Real-time co-editing and presence (v2 collaboration).
  • A version-history UI (the log exists; the UI follows).
  • Attachment blob pipeline changes (>25MB objects).
  • Shared-note permission model changes.

4Design

The client treats the local store as the system of record. Every mutation commits to SQLite and appends an operation to a durable outbox in the same transaction, so an acknowledged edit can never be lost to a crash or a dead radio.

4.1Local store & data model

SQLite on iOS, Android, and desktop; wa-sqlite over IndexedDB on web. A note is a document (note_id = UUIDv7) with scalar fields and a CRDT body:

FieldRepresentationMerge rule
bodySequence CRDT (RGA, tombstoned chars)Character-level merge, deterministic interleave
title · pinned · colorScalarPer-field last-writer-wins on HLC
sort_keyFractional indexLWW; rebalanced when neighbors collide
deleted_atTombstone (30d retention)Delete wins; edited copy is preserved

4.2Operation log & ordering

Each mutation emits an op {op_id, note_id, actor_id, hlc, type, payload}. A hybrid logical clock orders ops causally without trusting wall time; ties break on actor_id. Ops are idempotent, so replayed pushes are safe no-ops.

LOCAL STORESQLite · source of truth
SYNC ENGINEoutbox · push / pull
SERVERop log + snapshots
Fig 1 — one direction per half-loop; either side may fail independently
RFC-0142 · Offline-First Sync Notes Engineering Page 1 / 2
RFC-0142 Offline-First Sync for Notes

4.3Sync loop

  1. Push — batch outbox ops (≤100 ops or 256KB) to POST /sync/push; the server appends to the per-user log and returns a durable cursor.
  2. PullGET /sync/pull?cursor=c returns ops after c; apply in HLC order, checkpoint the cursor.
  3. Catch-up — a missing or stale cursor (>90d server retention) triggers a snapshot + fresh cursor; the client rebuilds rather than replays.
  4. Scheduling — run on connectivity change, foregrounding, and every 30s while dirty; exponential backoff capped at 5min. Push and pull are independent half-loops, so a one-way failure never stalls the other.

4.4Conflict handling

5Alternatives Considered

ApproachWhy it loses
Whole-note LWWAny concurrent edit silently discards one side — unacceptable for text, the field that matters most.
Operational TransformRequires a central sequencer and transform functions; more machinery than our scale justifies. A CRDT gives the same merge UX with no server coupling.
Managed sync (PowerSync, Realm, Firestore)Faster to ship, but plaintext routing metadata weakens our E2EE posture and per-MAU pricing compounds. Revisit for v2 collaboration.
Git-style 3-way mergeNeeds per-device ancestor tracking and a manual conflict UI — a poor fit for a consumer notes surface.

6Edge Cases & Failure Modes

7Migration & Rollout

8Open Questions

  1. Is 90 days of server op-log retention the right balance of storage cost vs. snapshot frequency? Pending infra cost model.
  2. Do conflict copies belong inline in the note list or in a separate Recovered folder? Needs design review (DES-0211).
  3. Does v2 collaboration reuse this op log, or do we adopt a hosted CRDT service at that point?
RFC-0142 · Offline-First Sync Notes Engineering Page 2 / 2