# Offline Support

### Introduction

Most messaging apps need to work regardless of whether the app is currently connected to the internet. Local data persistence stores the fetched data from the backend on a local SQLite database using the drift package in Flutter. All packages in the SDK can use local data persistence to store messages across multiple platforms.

### Implementation

To add data persistence you can extend the class `ChatPersistenceClient` and pass an instance to the `StreamChatClient`.

```dart
class CustomChatPersistentClient extends ChatPersistenceClient {
...
}

final client = StreamChatClient(
  apiKey ?? kDefaultStreamApiKey,
  logLevel: Level.INFO,
)..chatPersistenceClient = CustomChatPersistentClient();
```

We provide an official persistent client in the [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) package that works using the library [drift](https://drift.simonbinder.eu), an SQLite ORM.

Add this to your package's `pubspec.yaml` file, using the latest version.

```yaml
dependencies:
  stream_chat_persistence: ^latest_version
```

You should then run `flutter pub get`

The usage is straightforward.

1. Create a new instance of `StreamChatPersistenceClient` providing `logLevel` and `connectionMode`

```dart
final chatPersistentClient = StreamChatPersistenceClient(
  logLevel: Level.INFO,
  connectionMode: ConnectionMode.background,
);
```

2. Pass the instance to the official `StreamChatClient`

```dart
final client = StreamChatClient(
  apiKey ?? kDefaultStreamApiKey,
  logLevel: Level.INFO,
)..chatPersistenceClient = chatPersistentClient;
```

The `StreamChatClient` uses the `chatPersistentClient` to synchronize the database with the newest information every time it receives new data about channels, messages, and users.

### Connection mode

The `connectionMode` parameter controls which [isolate](https://dart.dev/language/concurrency#isolates) the persistence client uses to run its SQLite operations. It accepts a `ConnectionMode` value:

- `ConnectionMode.regular` (default) — The database runs on the main isolate, the same isolate that renders your UI.
- `ConnectionMode.background` — The database runs on a dedicated background isolate, so database work does not block the main thread.

If you do not provide a `connectionMode`, the client defaults to `ConnectionMode.regular`.

#### When and why to change it

With `ConnectionMode.regular`, all SQLite reads and writes run on the main isolate. Because Flutter also renders your UI on that isolate, large or frequent database operations can compete with frame rendering. For most apps — those with a moderate number of channels and messages — this is unnoticeable, which is why it is the default.

Switch to `ConnectionMode.background` if your app loads a large number of channels or messages, or if you notice UI jank during the initial sync or when reconnecting after being offline (moments when the SDK writes a large batch of data at once). Running the database on a background isolate keeps these heavy operations off the UI thread.

The trade-off is a small amount of overhead. Setting up the connection is slower than with `ConnectionMode.regular`, because a new background isolate has to be spawned when the client connects (the main isolate has no such startup cost). In addition, each query is passed between isolates. For typical workloads this overhead is negligible.

Note that `connectionMode` only takes effect on native platforms (iOS, Android, macOS, Windows, and Linux). On web it is ignored, since the web implementation does not use isolates.

### Multi-user

The database file is named after the `userId`, so if you instantiate a client using a different `userId` you will use a different database. Calling `client.disconnectUser(flushChatPersistence: true)` flushes all current database data.

### Updating/deleting/sending a message while offline

The information about the action is saved in offline storage. When the client returns online, all pending actions are retried.


---

This page was last updated at 2026-08-10T16:00:45.198Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/flutter/basics/offline-support/](https://getstream.io/chat/docs/sdk/flutter/basics/offline-support/).