docs/wiki/3.06-User-Data.md
The User Data concept applies only to the desktop (Electron) application. The web app stores data in browser storage (IndexedDB and localStorage) instead. See [[3.05-Web-App-vs-Desktop]] for web vs desktop differences. For an overview of how import, export, backups, and sync work from a user perspective, see [[4.23-Managing-Your-Data]].
A full backup or export includes all application data: tasks (active and archived), projects, tags, time-tracking state, global configuration, notes, reminders, metrics, simple counters, planner and board state, task repeat configurations, issue-provider settings, plugin user data, and both archive tiers (recent and old). No data is excluded from a complete backup or export.
The User Data Folder is the application data directory where the desktop app stores:
styles.css)| Platform | Location |
|---|---|
| macOS | ~/Library/Application Support/superProductivity/ |
| Windows | C:\Users\<YOUR_USER_NAME>\AppData\Roaming\superProductivity/ or %APPDATA%\superProductivity |
| Linux | ~/.config/superProductivity/ |
The path is shown in the UI under Settings → Automatic Backups (without the backups subfolder) and is printed when the app is started from the command line.
You can specify a custom user data directory using the --user-data-dir command-line parameter:
superproductivity --user-data-dir=/path/to/my/data
Trailing slashes are stripped. The custom path is used instead of the default for the session.
For Snap packages on Linux, the app uses the SNAP_USER_COMMON directory so that data is not accessed by the Snap update process. The effective path is $SNAP_USER_COMMON/.config/superProductivity (or the app name equivalent).
The Windows Store build uses a different path that includes the Windows Store package identifier (under Local\Packages\...\LocalCache\Roaming instead of Roaming).
{userData}/backups/.YYYY-MM-DD.json.YYYY-MM-DD.json.2025-01-15.json).styles.css (exact name required).ops, state_cache, import_backup, vector_clock, archive_young, archive_old. Holds operations log, state snapshots, vector clocks, and archives.UI and app state stored with keys such as:
SUP_UI_HELPER, SUP_ACTION_LOG, SUP_LAST_ERROR_ACTION_LOGSUP_IS_PROJECT_LIST_EXPANDED, SUP_IS_TAG_LIST_EXPANDEDDARK_MODE, SUP_NAV_SIDEBAR_EXPANDED, SUP_NAV_SIDEBAR_WIDTH, SUP_RIGHT_PANEL_WIDTHSUP_IS_ADD_TO_BOTTOM, and others (see storage-keys.const.ts for the full set).Automatic backups: When enabled in settings, the app creates a backup on a schedule (default: every 5 minutes). Storage location depends on platform:
| Platform | Where automatic backups are stored |
|---|---|
| Electron (desktop) | {userData}/backups/ as one JSON file per calendar day (YYYY-MM-DD.json) |
| Android | IndexedDB with key backup (single entry, overwritten) |
| iOS | Capacitor Filesystem API: super-productivity-backup.json in Directory.Data |
| Web | No automatic file backups; use "Export data" to download a file manually |
Manual backups: (1) Create manual backup in Settings → Sync & Export creates a backup using the same mechanism as automatic backups (platform-dependent location). (2) Safety backups are created automatically before certain sync operations; the app keeps a limited number of slots (e.g. two most recent, one first from today, one first from day before). (3) Export data downloads a complete backup JSON file to a path you choose (or the browser download folder on web).
What is included: All application data is included in backups and exports; nothing is excluded. When archives are included (e.g. when using "Export data" with full backup), both archive_young and archive_old are part of the file. A separate import backup (pre-import state) is stored in IndexedDB (import_backup store) only for recovery if an import fails; it is not part of the user-visible backup set.
Export: Export produces a snapshot of the current state at the time of export. The file is JSON containing (or wrapping) the full application state. Relationships are preserved by ID references (e.g. tasks reference projectId and tagIds; subtasks reference parentId). Export is available via Settings → Sync & Export → Import/Export (e.g. "Export data" / download backup).
Import: The app accepts a full backup in the same format (complete application state, optionally wrapped with timestamp and version). Supported structures: (1) the raw complete state object, or (2) a wrapper object with data, timestamp, and crossModelVersion where data is the complete state. Legacy V1 format (e.g. config + tasks array) is detected but no longer supported; the user is shown an alert that migration is not supported. Before applying import, the app validates the data (structure and cross-entity relationships). If validation fails, automatic repair may run when possible (e.g. fixing orphaned tasks, invalid project/tag references, missing archive structures). If the backup’s encryption state differs from the current app (encrypted vs unencrypted), the app shows a confirmation dialog before importing. After import, current state is replaced; archive data is written to IndexedDB. See [[2.02-Restore-Data-From-Backup]] for how to perform a restore.
Strategy: The app uses local-first, operation-based sync. The local device is the source of truth; sync exchanges operations (changes) rather than full state files each time. This reduces payload size and enables entity-level conflict detection.
Providers: Four sync providers are supported: SuperSync (server-based operation sync; very new, still in beta), WebDAV (file-based), Dropbox (file-based), and Local file (file-based, Electron/Android). File-based providers store a single sync file (e.g. sync-data.json) containing a full state snapshot plus a buffer of recent operations and a vector clock for causality.
Conflict resolution: Conflicts are detected using vector clocks (same entity changed in two places before sync). Resolution is last-write-wins (LWW): the operation with the newer timestamp wins; if timestamps are equal, the remote (server) side wins. When local wins, the app creates a new update operation so local state is propagated on the next sync. Identical conflicts (e.g. both sides deleted the same entity or made the same change) are auto-resolved without user action. In first-sync situations where both local and remote already have data, the app may show a dialog to choose use local or use remote. After resolution, state is validated and repaired as needed.
User-editable:
System-managed (do not edit manually):
QuotaExceededError occurs, the app triggers emergency compaction (24-hour retention instead of 7 days) and uses a circuit breaker to avoid infinite retries.nodeExecution permission and explicit user consent.REPAIR operations for the log.SUP_OPS) is missing or corrupted, the app attempts to load from the legacy pf database and run genesis migration.backups/ via Settings → Sync & Export → Import/Export → Import from file. See [[2.02-Restore-Data-From-Backup]].SyncStateCorruptedError and expects a full re-sync to restore consistent state.SUP_OPS, state_cache) and in localStorage (SUP_* and related keys).SUP_OPS is at schema version 4.src/environments/versions.ts), not stored in the User Data Folder.app.getPath('userData'); custom path set with app.setPath('userData', path) when --user-data-dir or Snap logic is used.getUserDataPath()).fs APIs (e.g. readFileSync, writeFileSync, readdirSync, statSync, unlinkSync) are used for backup and local file sync.