Skip to content

Persistence and Local Data

QenTerra edited this page Jul 29, 2026 · 1 revision

Persistence and Local Data

Unspool stores only the local state needed for account continuity, faster browsing, download recovery, and user preferences.

Storage map

Data Mechanism File or key Retention
API ID and API hash macOS Keychain Service com.qenterra.unspool.telegram-api Until edited, deleted, or successful Sign Out
TDLib database Application Support Unspool/TDLib/database Managed by TDLib and local app-data removal
TDLib file cache Application Support Unspool/TDLib/files Managed by TDLib and local app-data removal
Chat summaries JSON actor store Unspool/chats.json Current normalized set
Attachment scans JSON actor store Unspool/attachment-index.json 48 most recently updated snapshots
Download history JSON actor store Unspool/download-history.json 5,000 newest records
Interrupted batch JSON actor store Unspool/pending-download.json One pending batch
Destination permission Security-scoped bookmark Unspool/destination.bookmark Replaced when another folder is selected
Operational settings UserDefaults Namespaced preference keys Until app preferences are reset
Per-chat browse state UserDefaults Encoded chat-ID dictionary One state per encountered chat
Downloaded files User-selected folder Original filenames Controlled by the user

The exact Application Support prefix is chosen by macOS and may be inside the application's sandbox container.

JSON store behavior

Stores are actors so file reads and writes do not race across features. Writes use atomic Data.write options. Corrupt or unreadable optional cache files generally degrade to an empty cache rather than exposing raw decoder errors to the interface.

JSONChatSummaryStore uses sorted JSON keys for stable output and replaces its stored normalized list after relevant TDLib updates.

JSONAttachmentSnapshotStore keeps partial and complete scan snapshots keyed by chat and range. Saving a key moves it to the newest position before the 48-record cap is applied.

JSONDownloadHistoryStore sorts records newest first before applying the 5,000-record cap.

JSONPendingDownloadStore contains enough immutable batch input to restart preflight after relaunch. It is removed after completion, cancellation flow finishes, or explicit discard.

Preferences

Global preference keys store:

  • default scan range;
  • concurrent downloads;
  • per-chat folders;
  • reveal in Finder;
  • already-downloaded guard;
  • appearance;
  • encoded per-chat browse states.

Concurrency is normalized to 1–6 both when read and when changed.

Cache versus authority

Local stores are not Telegram's source of truth:

  • cached chat titles and positions can be replaced by live updates;
  • attachment snapshots represent a completed or partial scan at a point in time;
  • local download history does not prove a file still exists;
  • a destination bookmark does not prove the volume remains mounted;
  • pending conflicts must be recomputed before resuming.

This distinction is why Refresh, new preflight, and recoverable destination selection exist.

Clone this wiki locally