A delete is a change that has to sync
In a cloud app, deleting can be a single call to the server that holds the authoritative copy. In a local-first app every device holds a primary copy, so a delete is a change like any other: it is made on one device and has to reach the others.
It helps to separate three things people mean by “delete”:
- Hide it. The item disappears from the interface but the data stays.
- Forget it here. This device drops its copy, but other devices keep theirs.
- Remove it everywhere. Every replica applies the deletion and, eventually, discards the content.
The Ink & Switch essay on local-first software raises the hard version of the third case as an open question: if we can’t remove documents from others’ computers, what does it mean to “stop sharing” with someone?
Why deleted data lingers in merging data structures
Conflict-free replicated data types have to cope with a delete arriving before, after or alongside other changes. Shapiro and colleagues’ study of CRDTs shows the basic technique with a two-phase set: removed elements go into a second set, colloquially the tombstone set. The tombstone is what makes a remove still take precedence if a replica receives it before the matching add.
Tombstones have a cost. The same report notes that CRDTs tend to become inefficient over time as tombstones accumulate, and that safely removing tombstones needs agreement among all replicas: the set of replicas must be known and all of them reachable.
Libraries handle this differently:
- Yjs flags a deleted item rather than recording when or by whom it was deleted. With garbage collection on, the content of a deleted object is discarded and replaced by a lightweight structure that stores only its length. With
doc.gcset to false, old content is kept so it can be restored. - Automerge was the library behind the Ink & Switch prototypes. Their essay reported that because the CRDTs stored all history, including character-by-character edits, that history could not easily be truncated: a collaborator might reconnect months later and need to merge.
So “removed from the document” and “gone from the bytes on disk” are not the same thing. Check which one your library gives you.
Local storage keeps traces too
Below the document format sits the storage engine. SQLite’s documentation says that when content is deleted it is not usually erased; the space is marked for reuse, which can allow deleted content to be recovered by forensic analysis. Running VACUUM rebuilds the database and removes all traces of deleted content, and setting PRAGMA secure_delete=ON is the documented alternative.
Backups are another copy. Apple says iCloud Backup includes app data for downloaded apps unless the app stores it in iCloud Drive, and that if a user turns off iCloud Backup for a device, backups already stored are kept for 180 days before being deleted. A deletion plan has to account for copies like these that the app does not control directly.
Evicting a copy versus removing a document
Sync libraries can offer separate operations for “forget it here” and “remove it everywhere”, and they are easy to confuse. Offline Protocol’s shared state guide is a concrete example. deleteDoc evicts this device’s copy, and a peer can restore it. removeDoc propagates removal, but a concurrent edit can preserve and restore the document. The guide’s advice is to use a fresh document name for new content rather than relying on removal as a permanent tombstone.
The lesson carries over to other libraries. If a removal can race with an edit made offline, do not reuse an identifier and expect the old content to stay gone.
Erasure requests and the account lifecycle
Some deletions are legal obligations. Article 17 of the EU General Data Protection Regulation gives people the right to have personal data erased without undue delay on certain grounds, such as withdrawing consent. Where a controller has made the data public, it must take reasonable steps, considering available technology and cost, to inform other controllers processing it that erasure of any links, copies or replications has been requested. This is not legal advice; check what applies to your app.
In a local-first app, an erasure or account deletion plan should cover:
- server-side copies, relay queues and logs;
- a delete or removal that syncs to the user’s other devices;
- local databases, compacted or vacuumed so the content is gone from disk;
- keys and identity material in the platform key store (see where an app’s data lives on a phone);
- backups, and how long they are retained.
Devices that are offline, or belong to other people, may never apply the deletion. Say so honestly in your product, and limit what spreads in the first place by keeping each shared document to the people who need it.