Slow Mode & Throttling

For live events or concerts, you can sometimes have so many users, that the sheer volume of messages overloads the browser or mobile device. This can cause the UI to freeze, high CPU usage, and degraded user experience. Stream offers 3 features to help with this:

  1. Channel Slow Mode

  2. Automatic feature Throttling

  3. Message Throttling

Stream scales to 5 million concurrent users on a channel, see Scaling Chat to 5 Million Concurrent Connections.

Channel Slow Mode

Slow mode helps reduce noise on a channel by limiting users to a maximum of 1 message per cooldown interval.

The cooldown interval is configurable and can be anything between 1 and 120 seconds. For instance, if you enable slow mode and set the cooldown interval to 30 seconds a user will be able to post at most 1 message every 30 seconds.

Moderators, admins and server-side API calls are not restricted by the cooldown period and can post messages as usual.

Slow mode is disabled by default and can be enabled/disabled via the Dashboard, using the Chat Explorer:

It can also be enabled/disabled by admins and moderators via SDK.

// enable slow mode and set cooldown to 1s
await channel.enableSlowMode(1);

// increase cooldown to 30s
await channel.enableSlowMode(30);

// disable slow mode
await channel.disableSlowMode();

When a user posts a message during the cooldown period, the API returns an error message. You can avoid hitting the APIs and instead show such limitation on the send message UI directly. When slow mode is enabled, channels include a cooldown field containing the current cooldown period in seconds.

const p = channel.sendMessage(msg);

if (channel.data.cooldown != null && channel.data.cooldown > 0) {
  p.then(() => {
    // first lock the UI so that the user is aware of the cooldown
    disableSendMessageUI();
    // restore the UI after the cooldown is finished
    setTimeout(enableSendMessageUI, channel.data.cooldown);
  });
}

await p;

Automatic Feature Throttling

When a channel has more than 100 active watchers Stream Chat automatically toggles off some features. This is to avoid performance degradation for end-users. Processing large amount of events can potentially increase CPU and memory usage on mobile and web apps.

  1. Read events and typing indicator events are discarded

  2. Watcher start/stop events are only sent once every 5 seconds

Event throttling

Stream applies two control layers to protect clients and keep real-time behaviour predictable under load:

  • API throttles cap how often a given event type can be produced. Limits are scoped by entity key (per channel, per call, or per user), not globally across your app.
  • WebSocket queue throttles cap how quickly events are delivered over a single user connection. Each connection has three queues that prioritise traffic and smooth bursts.

Together, these limits keep delivery fair during spikes such as live events, concerts, or mass-notification scenarios, without dropping the events that matter most.

WebSocket queues

Every user connection drains events through three queues, each with its own per-connection rate limit:

QueueLimit (events/sec)Purpose
critical30Highest priority. System and access events where fast, reliable delivery matters most.
ordered15Preserves event order. Used for sequential streams such as messages and reactions.
mergeable10Coalesces repeated updates by key (latest wins) to reduce noisy state-change traffic.

If a burst exceeds a queue's limit, events continue to be delivered but at the queue's steady-state rate. Events on the mergeable queue may be collapsed so only the most recent update per key is sent.

API throttles per event

The tables below list the per-entity API throttle for each event type and the WebSocket queue it is delivered through. unlimited means no API-side cap is applied; delivery is still governed by the WebSocket queue.

API throttles are applied per entity key. For example, message.new at 10 events/sec applies per channel, and user.presence.changed at 8 events/sec applies per user. Separate channels or users do not share the same budget.

EventAPI throttle (events/sec)WS queueWS queue limit (events/sec)
* (custom events)8ordered15
ai_indicator.clear10ordered15
ai_indicator.stop10ordered15
ai_indicator.update10ordered15
channel.created5ordered15
channel.deleted5ordered15
channel.frozen10mergeable10
channel.hidden10ordered15
channel.kicked30critical30
channel.max_streak_changed10mergeable10
channel.truncated5ordered15
channel.unfrozen10mergeable10
channel.updated8mergeable10
channel.visible10ordered15
draft.deleted10mergeable10
draft.updated10mergeable10
member.added8ordered15
member.removed8ordered15
member.updated8ordered15
message.deleted8ordered15
message.delivered8ordered15
message.new10ordered15
message.pending15ordered15
message.read20ordered15
message.undeleted8ordered15
message.updated10ordered15
notification.added_to_channel8critical30
notification.channel_deleted8critical30
notification.channel_mutes_updated8mergeable10
notification.channel_truncated8critical30
notification.invite_accepted8critical30
notification.invite_rejected8critical30
notification.invited8critical30
notification.mark_read20critical30
notification.mark_unread10critical30
notification.message_new10critical30
notification.mutes_updated8mergeable10
notification.reminder_dueunlimitedcritical30
notification.removed_from_channel8critical30
notification.thread_message_new10critical30
poll.closed15ordered15
poll.deleted15ordered15
poll.updated15ordered15
poll.vote_casted15ordered15
poll.vote_changed15ordered15
poll.vote_removed15ordered15
reaction.deleted10ordered15
reaction.new10ordered15
reaction.updated10ordered15
reminder.created15ordered15
reminder.deleted15ordered15
reminder.updated15ordered15
thread.updated10mergeable10
typing.start10ordered15
typing.stop10ordered15
user.messages.deleted15critical30
user.muted10mergeable10
user.watching.start5ordered15
user.watching.stop5ordered15

If you are on an Enterprise Plan, throttling limits can be adjusted for your application by our support team.