# Livestream Chat

High-traffic channels like livestreams can generate thousands of messages per minute. The SDK provides configuration options to optimize memory usage and performance for these scenarios.

## Message Limiting

The `MessageLimitConfig` allows you to control how many messages are kept in memory for different channel types. When the message count exceeds the configured limit, older messages are automatically trimmed from memory while keeping the most recent ones.

### Configuration

Configure message limits when setting up the `StatePlugin`:

```kotlin
val statePluginFactory = StreamStatePluginFactory(
    config = StatePluginConfig(
        messageLimitConfig = MessageLimitConfig(
            channelMessageLimits = setOf(
                // Limit livestream channels to 500 messages in memory
                ChannelMessageLimit(channelType = "livestream", baseLimit = 500),
                // Limit messaging channels to 1000 messages in memory
                ChannelMessageLimit(channelType = "messaging", baseLimit = 1000),
            ),
        ),
    ),
    appContext = context,
)

ChatClient.Builder(apiKey, context)
    .withPlugins(statePluginFactory)
    .build()
```

### How It Works

- When the message count exceeds `baseLimit + 30` (buffer), the SDK trims messages down to `baseLimit`
- Messages are sorted by creation time; only the most recent ones are kept
- Trimming only occurs when not loading older messages (to avoid interfering with pagination)
- If loading older messages causes the count to exceed the limit, the limit is temporarily increased by 1.5x
- The `endOfOlderMessages` flag is set to `false` when trimming occurs, indicating more messages are available but not yet loaded in memory
- Messages are only removed from in-memory state, not from the local database

### UI Integration

If you're using Jetpack Compose, the `MessageList` component works seamlessly with message limiting. Compose's `LazyColumn` only renders visible items, providing efficient virtualization automatically:

```kotlin
MessageList(
    viewModel = messageListViewModel,
    // Messages are automatically limited based on your MessageLimitConfig
)
```

For custom implementations, observe the message state from `ChannelState`:

```kotlin
val channelState: StateFlow<ChannelState?> = chatClient.watchChannelAsState(cid, messageLimit = 30)

channelState
    .filterNotNull()
    .flatMapLatest { it.messages }
    .collectLatest { messages ->
        // Messages are already limited based on your configuration
        updateUI(messages)
    }
```

## Skipping Database Storage

For channels where message persistence is not needed (e.g., ephemeral livestream messages), you can configure the `OfflinePlugin` to skip database storage entirely. This reduces disk I/O and improves performance.

### Configuration

Configure ignored channel types when setting up the `OfflinePlugin`:

```kotlin
val offlinePluginFactory = StreamOfflinePluginFactory(
    appContext = context,
    // Messages in these channel types won't be stored in the local database
    ignoredChannelTypes = setOf("livestream"),
)

ChatClient.Builder(apiKey, context)
    .withPlugins(statePluginFactory, offlinePluginFactory)
    .build()
```

### Behavior

When a channel type is in `ignoredChannelTypes`:

- Messages are not persisted to the local database
- Reactions in these channels are not stored locally
- The channel still receives real-time updates via WebSocket

This is useful for high-volume channels where:

- Messages are ephemeral and don't need offline access
- Reducing database writes improves performance
- Storage space is a concern

## Complete Setup Example

Here's a complete example combining both optimizations for a livestream use case:

```kotlin
// Configure state plugin with message limiting
val statePluginFactory = StreamStatePluginFactory(
    config = StatePluginConfig(
        messageLimitConfig = MessageLimitConfig(
            channelMessageLimits = setOf(
                ChannelMessageLimit(channelType = "livestream", baseLimit = 500),
            ),
        ),
    ),
    appContext = context,
)

// Configure offline plugin to skip DB for livestream channels
val offlinePluginFactory = StreamOfflinePluginFactory(
    appContext = context,
    ignoredChannelTypes = setOf("livestream"),
)

// Build ChatClient with both plugins
ChatClient.Builder(apiKey, context)
    .withPlugins(statePluginFactory, offlinePluginFactory)
    .build()
```

With this configuration:

- Livestream channels keep only the 500 most recent messages in memory
- Messages are not written to the local database
- Real-time updates continue to work normally
- Memory and disk usage remain controlled even with high message volume


---

This page was last updated at 2026-04-21T07:55:27.003Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/android/v6/client/guides/livestream-chat/](https://getstream.io/chat/docs/sdk/android/v6/client/guides/livestream-chat/).