State Overview

Our UI Components and Compose UI Components rely on reading the state in order to render the UI. Information such as the currently active user, list of muted users, online status, etc. is saved as state inside various state holders (for exampleGlobalState, and others). The state is managed by StatePlugin and adding it to ChatClient is mandatory if you want to use our UI Components/Compose UI Components.

Let’s see how we can add the plugin:

// Create a state plugin factory
val statePluginFactory = StreamStatePluginFactory(
    config = StatePluginConfig(
        // Enables/disables background synchronization when push notifications are received
        backgroundSyncEnabled = true,
        // Enables/disables tracking online states for users
        userPresence = true,
        // Enables/disables automatic sync on reconnect
        isAutomaticSyncOnReconnectEnabled = true,
        // Sets the maximum age threshold for pending local operations before they are discarded
        syncMaxThreshold = TimeDuration.hours(12),
        // Function to provide the current time in milliseconds since epoch
        now = { System.currentTimeMillis() },
        // Configuration for message limits in memory
        messageLimitConfig = MessageLimitConfig(
            // Set a limit of 500 messages for `livestream` channels
            channelMessageLimits = setOf(ChannelMessageLimit("livestream", 500)),
        ),
    ),
    appContext = context
)

ChatClient.Builder(apiKey, context)
    // Add the state plugin to the chat client
    .withPlugins(statePluginFactory)
    .build()

The StatePluginConfig allows you to configure the following options:

  • backgroundSyncEnabled: Controls whether the SDK performs background synchronization when push notifications are received. When enabled (default: true), the SDK automatically syncs messages in the background when a push notification arrives, ensuring the local state/database stays up-to-date even when the app is in the background. This is particularly useful for displaying accurate notification content and maintaining offline state consistency. Disable this if you want to reduce background processing.
The background sync on push notification flag (backgroundSyncEnabled) is no longer needed to keep the state in sync and will be removed in the future. If you are using the default UI components, or building your own UI using the ChatClient.queryChannelsAsState / ChatClient.watchChannelAsState methods, the state will always be up-to-date. We recommend disabling it to avoid unnecessary background work.
  • userPresence: Controls whether the SDK subscribes to and processes user presence events (online/offline status, last active time). When enabled (default: true), the SDK receives real-time updates about user presence changes and updates the user objects in channels, members, and watchers accordingly. This affects both WebSocket event subscriptions and the presence parameter in API requests. Disabling this can reduce network traffic and processing overhead if your application doesn’t need to display user online/offline status.
  • isAutomaticSyncOnReconnectEnabled: Specifies if local data is updated with subscribing to web-socket events after reconnection. When turning this off, it is up for SDK user to observe web-socket connection state for reconnection and syncing data by calling, for example ChatClient.queryChannels, or the StatePlugin methods such as ChatClient.queryChannelsAsState / ChatClient.watchChannelAsState.
  • syncMaxThreshold: The maximum age threshold for pending local operations (channels, messages, reactions) before they are considered too old to retry and are discarded. Default is 12 hours. When the SDK attempts to retry failed operations (e.g., sending a message, creating a channel, adding a reaction) upon reconnection, it checks if the operation’s timestamp (createdLocallyAt, updatedLocallyAt, deletedAt, or createdAt) exceeds this threshold. If it does, the operation is removed from the local database instead of being retried, preventing the SDK from attempting to sync stale operations that are no longer relevant.
  • now: A function that provides the current time in milliseconds since epoch (Unix timestamp). Defaults to System.currentTimeMillis. This is used throughout the state plugin for time-based operations such as calculating sync thresholds. In general, this is not something that needs to be overridden unless you have specific requirements for time handling in your application.
  • messageLimitConfig: Configuration that controls the maximum number of messages kept in memory for different channel types. This helps manage memory usage in channels with large message histories. When the number of messages exceeds the configured limit (plus a buffer), older messages are automatically trimmed from the in-memory state. By default, no limits are applied, meaning all messages are kept in memory. See MessageLimitConfig and ChannelMessageLimit for configuration details.
© Getstream.io, Inc. All Rights Reserved.