# What Is the Data Serialization Format for Local Settings Storage in Telegram Desktop?

> Discover how Telegram Desktop saves local settings using Qt's QDataStream binary format ensuring backward compatibility with a fixed version. Learn about its sequential field layout.

- Repository: [Telegram Desktop/tdesktop](https://github.com/telegramdesktop/tdesktop)
- Tags: internals
- Published: 2026-04-05

---

**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`](https://github.com/telegramdesktop/tdesktop/blob/main/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 by `Core::Settings`)
- **Session settings**: `tdata/sessions/<session-id>/settings` (managed by `Main::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`](https://github.com/telegramdesktop/tdesktop/blob/main/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.

```cpp
// 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`](https://github.com/telegramdesktop/tdesktop/blob/main/Telegram/SourceFiles/storage/localstorage.cpp) (lines 95-96), Telegram implements `CheckStreamStatus` to validate the stream after every read operation.

```cpp
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`](https://github.com/telegramdesktop/tdesktop/blob/main/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`](https://github.com/telegramdesktop/tdesktop/blob/main/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`](https://github.com/telegramdesktop/tdesktop/blob/main/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:

1. **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.
2. **Always validate stream status**: Use `CheckStreamStatus` after every read operation to detect file corruption, truncation, or version mismatches, as implemented in [`localstorage.cpp`](https://github.com/telegramdesktop/tdesktop/blob/main/localstorage.cpp).
3. **Maintain the Qt_5_1 version**: Do not change the `QDataStream` version constant without a comprehensive migration strategy, as this would immediately invalidate all existing user settings files.

## Summary

- Telegram Desktop uses **Qt's `QDataStream`** with version **Qt_5_1** for all local settings serialization.
- Settings are stored as binary blobs in the `tdata` directory, with application settings in `tdata/settings` and session settings in `tdata/sessions/<session-id>/settings`.
- The implementation in [`core_settings.cpp`](https://github.com/telegramdesktop/tdesktop/blob/main/core_settings.cpp) writes data sequentially via `writePrefGeneric`, while [`localstorage.cpp`](https://github.com/telegramdesktop/tdesktop/blob/main/localstorage.cpp) handles stream validation via `CheckStreamStatus`.
- 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 (`\x1` for 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`](https://github.com/telegramdesktop/tdesktop/blob/main/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`](https://github.com/telegramdesktop/tdesktop/blob/main/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.