On this page

Live event rate limiting

Live events with thousands or millions of concurrent viewers create unique challenges for real-time systems. When too many messages flood a single channel, the chat becomes unreadable and the user experience suffers.

PubNub's Functions-based rate limiter provides dynamic message throttling that maintains optimal user experience while preserving the feeling of being part of a massive live audience. This is the recommended approach for most high-occupancy live events.

For events with natural audience divisions (such as different languages or team affiliations), channel sharding offers an alternative approach that creates separate conversation spaces.

By the end of this document, you will understand:

  • How message frequency affects user experience
  • How the Functions rate limiter maintains engagement while controlling message flow
  • When channel sharding makes sense (logical groupings only)
  • Best practices for live event messaging

How PubNub helps

Role in the solutionPubNub feature (click to learn more!)
  • Dynamic message throttling
  • Automatic rate control based on traffic
Functions
  • Real-time messaging
  • Distribute audiences across channels (if sharding)
Pub/Sub
  • Monitor channel occupancy
  • Track user join and leave events
Presence

Use case overview

Recommended approach

The Functions-based rate limiter is the recommended solution for most live events. It maintains the feeling of being part of a massive shared experience while controlling message flow to keep chat readable.

When 100,000 fans are celebrating together, you want them to feel the energy of the crowd—not feel separated into smaller rooms. The Functions rate limiter achieves this by intelligently throttling message rates while keeping all users in a single shared channel.

This approach:

  • Preserves the "stadium atmosphere" where users feel part of the full audience
  • Dynamically adjusts throttling based on current message rates
  • Requires no user separation or channel assignment logic
  • Works automatically with minimal configuration

For complete implementation details and sample code, see Rate Limiting.

Consider a live soccer match between Chelsea FC and Southampton FC streamed to 100,000 viewers. As exciting moments happen, such as a controversial call or someone scoring an absolute screamer, thousands of fans want to share their reactions simultaneously. Without rate limiting, this creates several problems:

  • Chat becomes unreadable when hundreds of messages appear per second
  • High message volume makes it impossible to follow conversations
  • Participants can't see their own messages or engage meaningfully

The Functions rate limiter solves these challenges by intelligently throttling message rates while keeping all 100,000 fans in a shared experience. Users feel like they're part of a massive stadium crowd, not separated into smaller rooms.

Message frequency and readability

Real-time systems can easily become "noisy" when too many participants send messages simultaneously. In use cases where audience dialogue is important, too much noise lowers attention span until the chat reaches a saturation point that makes meaningful conversation impossible.

The saturation point varies depending on your use case.

OutcomeRecommended message rateExperience type
Meaningful conversations between attendees
Lower message rates
Dialogue-focused experiences
Excitement and energy; conversation is less of a priority
Higher message rates
Engagement-focused experiences

Channel sharding

When to use channel sharding

Channel sharding is appropriate only when logical groupings exist, such as different languages, team affiliations, or geographic regions. If there's no natural way to divide your audience, use the Functions rate limiter instead to preserve the shared experience.

Channel sharding divides your audience into separate conversation spaces. Unlike the Functions rate limiter, this approach separates users into distinct rooms rather than keeping them in a shared experience.

Channel sharding makes sense when there are logical groupings, such as:

  • Language-based separation, such as Spanish-speaking fans chat with other Spanish speakers
  • Team affiliation, such as Home and away fan sections
  • Geographic regions, such as Local fan communities
  • Premium tiers, such as VIP rooms for special access

When to avoid channel sharding:

  • You want users to feel part of the full audience ("100k stadium" experience)
  • There's no logical way to group users
  • Random distribution would fragment the community feel

Considerations

When implementing channel sharding with logical groupings, consider these trade-offs.

AdvantagesConsiderations
Creates relevant conversation groups
Users in different shards have different experiences
All messages reach participants in the group
Requires monitoring occupancy if audience size is unpredictable
Logical groupings improve engagement and "stickiness"
Channel rebalancing may be needed if users leave unevenly
Ideal for language or team-based separation
Additional logic needed for channel assignment

Channel sharding implementation

If you've determined that channel sharding is appropriate for your use case (because you have logical groupings), here's how to implement it.

Logical grouping

The only recommended sharding approach groups users by logical criteria that enhance the experience:

1// Example: Shard by language preference
2async function assignChannelByLanguage(userId, language) {
3 const channelId = `game.chat.${language}`;
4
5 await pubnub.subscribe({
6 channels: [channelId]
7 });
8
9 return channelId;
10}
11
12// Usage
13const userChannel = await assignChannelByLanguage("user-123", "es");
14// Result: "game.chat.es" for Spanish-speaking users

Common logical groupings for sports and entertainment:

  • Language - separate channels for different languages
  • Geographic region - regional channels for local fans
  • Team affiliation - separate home and away team fan channels
  • Experience level - channels for casual and hardcore fans

This approach improves both cost efficiency and user experience by creating more relevant conversation groups. For example, users who speak Portuguese can chat with other Portuguese-speaking users, and users who are hardcore fans of Chelsea FC can chat with other hardcore fans of Chelsea FC.

Dynamic assignment with Presence monitoring

For logical groupings with unpredictable audience sizes, use Presence to monitor occupancy within each logical group.

1// Monitor channel occupancy and assign users to balanced channels
2async function assignToDynamicChannel(userId, targetOccupancy = 1000) {
3 const baseChannel = "game.chat";
4 let assignedChannel = null;
5 let shardIndex = 0;
6
7 // Check channels until we find one below target occupancy
8 while (!assignedChannel) {
9 const channelId = `${baseChannel}.shard-${shardIndex}`;
10
11 try {
12 // Check current occupancy using Presence
13 const response = await pubnub.hereNow({
14 channels: [channelId]
15 });
show all 38 lines
icon

Required Admin Portal config


AdvantagesConsiderations
Adapts to changing audience sizes
Server-side monitoring of channel occupancy
Maintains balanced occupancy across channels
Additional logic to handle channel rebalancing
Creates new channels automatically as needed
Management of users leaving channels

Monitor channel health

Once your sharded channels are running, monitor their performance to ensure optimal user experience.

1// Monitor occupancy across all shards
2async function monitorShardOccupancy(baseChannel, shardCount) {
3 const channels = Array.from(
4 { length: shardCount },
5 (_, i) => `${baseChannel}.shard-${i}`
6 );
7
8 const response = await pubnub.hereNow({
9 channels: channels,
10 includeState: false
11 });
12
13 // Analyze occupancy distribution
14 const occupancyReport = channels.map(channelId => ({
15 channel: channelId,
show all 26 lines

Key metrics

MetricPurpose
Average occupancy per shard
Ensure channels aren't becoming too crowded.
Occupancy distribution
Identify imbalanced shards that may need adjustment.
Message rate per shard
Verify that message frequency remains readable.
User feedback
Monitor complaints about chat speed or visibility.

Best practices

When implementing rate limiting for live events, follow these best practices.

Choose the right approach

Start by determining whether you need channel sharding or the Functions rate limiter.

SituationRecommended approach
You want users to feel part of the full audience
Functions rate limiter
You have natural audience divisions (language, team, region)
Channel sharding
You're unsure
Start with Functions rate limiter

Most live events benefit from the Functions rate limiter because it preserves the shared experience of being part of a massive audience.

Channel sharding: use logical groupings only

Only implement channel sharding when you have meaningful ways to group users. Logical groupings (language, region, team) create more engaging experiences. Random distribution fragments the community feel and we generallydon't recommend it.

Channel sharding: plan for uneven departures

Users don't leave evenly across shards. Some channels may empty while others remain active. Consider the following:

  • Migrating users from emptying channels to active ones
  • Accepting that some channels will have different occupancy
  • Focusing on the average experience rather than perfect balance

Test at scale

Before your event, simulate expected audience sizes, test your rate limiting configuration, verify monitoring performance, and ensure the experience meets your goals.

Consider complementary features

Rate limiting works well alongside other features:

  • Content moderation for chat safety
  • Broadcast channels (separate channels for official announcements that reach all users)
  • VIP rooms (special channels for premium users), a natural logical grouping for sharding

Additional resources

For more details on the approaches covered in this document, refer to:

Football club names are used for illustrative purposes only and do not imply any affiliation or endorsement.

Last updated on