What Is the Data Serialization Format for Local Settings Storage in Telegram Desktop?
Telegram Desktop serializes both application-level and session-level settings as binary blobs using Qt's QDataStream with a fixed version of Qt 5.1, enforcing sequential field layout to maintain backward compatibility.
Telegram Desktop persists user preferences and session data in local binary files within the tdata directory. The application uses a specific data serialization format for local settings storage that relies on Qt's native binary stream protocol to ensure cross-platform consistency across Windows, macOS, and Linux without external conversion layers.
Binary Serialization with QDataStream
The serialization implementation centers on QDataStream, Qt's binary data serialization class. Unlike text-based formats such as JSON or XML, Telegram Desktop opts for a compact binary representation to minimize disk footprint and maximize read/write performance while maintaining strict layout control.
Fixed Stream Version and Compatibility
According to the source code in Telegram/SourceFiles/storage/localstorage.cpp (lines 149-150), the stream version is explicitly locked to QDataStream::Qt_5_1. This hardcoded version ensures that the binary layout remains stable across different Qt library versions and operating system updates. The development team enforces a strict append-only policy: new fields must always be added to the end of the stream, allowing older application versions to read files created by newer releases without misinterpreting byte positions.
Storage Location and Structure
Settings are stored in two primary locations within the tdata directory:
- Application settings:
tdata/settings(managed byCore::Settings) - Session settings:
tdata/sessions/<session-id>/settings(managed byMain::SessionSettings)
Each setting value is converted to a QByteArray before being written to the stream, creating a standardized binary envelope for all data types regardless of their native C++ representation.
Writing Settings to Disk
The write operation is implemented in Telegram/SourceFiles/core/core_settings.cpp around line 1205 within the writePrefGeneric method. The code constructs a QDataStream object bound to the settings file and serializes key-value pairs sequentially.
// Simplified from Core::Settings::writePrefGeneric
void Settings::writePrefGeneric(std::string_view key, const QByteArray &value) {
QFile file(_path); // Path points to tdata/settings
QDataStream stream(&file);
stream.setVersion(QDataStream::Qt_5_1); // Fixed version
// Write key then value as binary blobs
stream << QByteArray(key.data(), key.size());
stream << value;
}
Boolean values receive special handling in writePrefImpl<bool>: they are encoded as either a single byte \x1 for true or an empty QByteArray for false, minimizing storage overhead for common flags.
Reading Settings Back
The deserialization process mirrors the write operation exactly. The same Qt_5_1 stream version must be used to ensure binary compatibility. In Telegram/SourceFiles/storage/localstorage.cpp (lines 95-96), Telegram implements CheckStreamStatus to validate the stream after every read operation.
QDataStream stream(&file);
stream.setVersion(QDataStream::Qt_5_1);
QByteArray key, value;
stream >> key >> value; // Order must match write sequence
// Validation as implemented in CheckStreamStatus
if (stream.status() != QDataStream::Ok) {
// Handle corruption or version mismatch
}
If the stream status deviates from QDataStream::Ok, the application treats the settings file as corrupted and handles the error appropriately, typically by falling back to default values.
Implementation Details in the Source Code
Core Settings Implementation
The Core::Settings class in Telegram/SourceFiles/core/core_settings.cpp provides the high-level API through template methods like writePref and readPref. These methods delegate to writePrefGeneric, which handles the actual binary serialization using QDataStream as shown at line 1205.
Low-Level Storage Helpers
Telegram/SourceFiles/storage/localstorage.cpp contains the infrastructure for file I/O and stream validation. Lines 149-150 initialize the QDataStream with the Qt_5_1 version constant, while lines 95-96 define the CheckStreamStatus utility that guards against data corruption during reads by verifying stream.status().
Session-Level Settings
Session-specific configurations, such as call-related settings, follow the same binary protocol. In Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp (lines 1136-1137), the code reads binary blobs for session data using an identical QDataStream configuration, ensuring consistency between global and per-session storage implementations.
Critical Rules for Developers
When modifying the settings storage system, the Telegram Desktop codebase enforces three fundamental rules derived from its binary serialization architecture:
- Never insert fields mid-stream: Always append new data to the end of the binary sequence to maintain backward compatibility with older application versions that expect specific byte offsets.
- Always validate stream status: Use
CheckStreamStatusafter every read operation to detect file corruption, truncation, or version mismatches, as implemented inlocalstorage.cpp. - Maintain the Qt_5_1 version: Do not change the
QDataStreamversion constant without a comprehensive migration strategy, as this would immediately invalidate all existing user settings files.
Summary
- Telegram Desktop uses Qt's
QDataStreamwith version Qt_5_1 for all local settings serialization. - Settings are stored as binary blobs in the
tdatadirectory, with application settings intdata/settingsand session settings intdata/sessions/<session-id>/settings. - The implementation in
core_settings.cppwrites data sequentially viawritePrefGeneric, whilelocalstorage.cpphandles stream validation viaCheckStreamStatus. - New fields must be appended to the end of the stream to ensure older clients can read files created by newer versions without breaking.
- Boolean values are encoded as single-byte arrays (
\x1for true, empty for false).
Frequently Asked Questions
What specific Qt version does Telegram Desktop use for its settings serialization?
Telegram Desktop explicitly sets the QDataStream version to Qt_5_1 when reading and writing local settings files. This fixed version, found in Telegram/SourceFiles/storage/localstorage.cpp at lines 149-150, ensures binary compatibility across different operating systems and Qt library versions installed on the host system.
Where are local settings files physically stored on disk?
Local settings are stored in the tdata directory within the application data folder. Application-level settings reside in tdata/settings, while session-specific settings are located in tdata/sessions/<session-id>/settings. Each file contains binary data written via QDataStream and is read back using the same stream version and sequence order.
How does Telegram Desktop handle corrupted settings files?
The application validates the QDataStream status after every read operation using the CheckStreamStatus utility defined in Telegram/SourceFiles/storage/localstorage.cpp (lines 95-96). If stream.status() returns anything other than QDataStream::Ok, the application detects corruption and handles the error appropriately, typically by resetting to default values or marking the session as invalid.
Can new settings fields be added to existing storage?
Yes, but they must follow the append-only rule. New fields can only be added to the end of the binary stream. This sequential layout ensures that older versions of Telegram Desktop can still read the file without breaking, as they simply stop reading before encountering the new fields that they do not recognize.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →