Backup, Export, and Restore
Backup is for recovery. Export is for user ownership and interoperability. They can share code, but they are not the same product feature.
| Feature | User expectation | Format |
|---|---|---|
| CSV export | inspect data in spreadsheets | lossy but human-friendly |
| JSON export | move data between app versions or tools | structured and readable |
| SQLite export | preserve relational structure | durable app document |
| Encrypted backup | restore private data later | complete and protected |
| Restore | replace or merge local state safely | validated import path |
SQLite Backup Options
Use the online backup API or VACUUM INTO for live databases. Avoid naive file copy while the DB is open in WAL mode.
VACUUM INTO 'backup.sqlite';
For very large databases, expose progress and allow cancellation. After backup, open the backup separately and run integrity checks.
PRAGMA integrity_check;
PRAGMA foreign_key_check;
Restore Drill
Every local-first app needs a clean-install restore drill:
- Create realistic data.
- Export or back up.
- Delete the app data directory or install on a clean device/profile.
- Restore.
- Verify counts, key rows, attachments, settings, and derived indexes.
- Run the app offline.
Import Policy
Before import, decide:
- replace all local data
- merge by stable IDs
- create a new workspace/document
- dry-run and show conflicts
- refuse unsupported versions
Gotcha: Restore is a destructive operation when it replaces local data. Take a pre-restore backup first.