# What local-first means in Prior

> Prior saves your work on your device first and syncs it after. How that works, how conflicts are merged for each kind of data, and where local-first stops.

Source: https://priortasks.com/blog/local-first/
Last updated: 2026-11-05

Local-first means the copy of your work that matters is the one on your device. The server is how your devices reach each other, not the place an action has to be approved before it counts. The idea was set out in 2019 by Martin Kleppmann, Adam Wiggins, Peter van Hardenberg and Mark McGranaghan at Ink & Switch, in [an essay](https://www.inkandswitch.com/essay/local-first/) that lists seven ideals: fast, multi-device, offline, collaboration, longevity, privacy and user control.

Prior's architecture follows this idea. Here is what it means in practice, and where it stops.

## What happens when you add a task

You write a task. Prior saves it in a database on your device: SQLite in the desktop and Android apps, the browser's own storage on the web. Next to it, it writes an entry in an outbox with a unique mutation ID. The task appears on screen at that point. Nothing waited for the network, which is why creating a task is instant.

When the device is online, it sends the outbox to the server. The server keeps an append-only log of changes with a revision number going up, and applies each change only once per mutation ID, so a retry after a dropped connection cannot create a task twice. Your other devices ask for what changed since the last revision they saw. A small WebSocket message tells them to ask now, instead of waiting for the next periodic sync. It carries no data, only the news that something changed.

Offline, the app says so: "Everything is saved on this device. It will sync when you're back online." With changes waiting, it counts them. Data created before you sign in stays on the device until it is attached to your account.

## Merging is a choice per kind of data

Two devices that change the same thing offline will disagree when they meet. There is no single fix for every kind of data, so Prior uses the one that fits each.

- **Tasks and habits.** The server applies the last accepted change in revision order. A task with a change still waiting on your device is not overwritten by what arrives from elsewhere.
- **Calendars and events.** Changes are patches by field. Edits to different fields of the same event combine; for the same field, the last one received wins. Deletions leave a marker, so an old offline copy cannot bring an event back.
- **Flashcards.** Reviews are an append-only log, and a card's schedule is not stored. It is computed by replaying that card's reviews. Two devices that reviewed offline end up with the same schedule once their logs meet, with nothing to resolve.
- **Budgets.** They merge line by line. The newest version of each line wins, and deleted lines leave a marker.
- **Shared notes.** They are Yjs documents, built for several people typing at once. If the connection drops, the note shows that it is offline, and editors' changes merge when they reconnect.

What the five share is a merge chosen for how the data is used, and a marker for every deletion, so an old copy can never undo a newer decision.

## Where it stops

Local-first is a promise about where your work lives and what keeps working, not a promise about everything.

- **Shared projects need a connection.** Prior says so and keeps a shared project read-only until you reconnect.
- **Some things are online by nature.** Signing in, Prior AI, email and leagues need the network.
- **It is not end-to-end encryption.** Your data is stored on our server so that it can sync. Local-first does not change that.
- **A browser is a fragile place.** On the web your data lives in that browser's storage. Clear it before the data has synced and the unsynced changes go with it. Native apps keep a database file.

## A bug that taught us something

An early version of the sync ran in a fixed order. A date column was read badly for scheduled tasks and made the whole task pull fail, which also stopped the calendars and the workspace from syncing. We fixed the read, and we changed the design: each part of the sync now runs on its own, and a failure in one no longer blocks the others. The interface says which part is still waiting, and it does not report a complete success when one part failed.

That is also local-first at work. Your data was never lost, because it was safe on the device. The sync was late.

More on using it is in [Offline and sync](https://priortasks.com/docs/getting-started/offline-and-sync/), and [Sync problems](https://priortasks.com/docs/troubleshooting/sync-problems/) covers what to do when something does not arrive.
