API usage restrictions

Updated

Signaling rate limits, quotas, and capacity limits, with guidance on planning your application's capacity.

This page describes the limits that apply to Signaling SDK 2.x and its RESTful APIs, what happens when your application exceeds a limit, and how to plan capacity. Use it to:

How limits work

Each Signaling limit applies at a specific level and has a type that determines what happens when you exceed it.

Limit levels

Signaling limits apply at four levels. Higher levels limit total volume, and lower levels limit individual objects. A single call can be subject to limits at more than one level.

LevelApplies toWhen exceeded
AccountYour Agora accountThe RESTful API returns a quota error.
Project (App ID)One projectMost project limits are recommendations. Contact support before you exceed them.
ChannelOne channelCapacity limits return errors. Rate limits are recommendations.
ClientOne Signaling client instanceThe SDK reports an error in a callback.

Limit types

Each limit has one of the following types:

TypeMeaningWhen exceededCan you change it?
Fixed limitA hard system constraint.The call fails and returns an error.No.
Default limitThe default quota.The call fails and returns an error.Yes. See Request higher limits.
Recommended valueThe range that provides the best performance.Usually, no error is returned.Contact support before you exceed it.
Unlimited countThe resource has no count limit.Not applicable.Not applicable. Rate and throughput limits still apply.

Account-level limits

The following limit applies to all projects in your Agora account:

LimitValueTypeDescription
Total RESTful API request rate per account1,000 requests per secondDefault limitThe total across all projects and RESTful APIs in the account. Requests above this rate return HTTP 429.

Project-level limits (App ID)

The following limits apply to each project, identified by its App ID:

LimitValueTypeDescription
Peak concurrent users (PCU)200,000Recommended valueIf you expect to exceed this value, contact support in advance. See Estimate PCU.
Total upstream message rate100,000 messages per secondRecommended valueThe total number of messages that all clients and RESTful APIs in the project send.
Number of message channelsUnlimitedUnlimited countSignaling creates channels as needed. You don't need to create them in advance.
Number of stream channelsUnlimitedUnlimited countSignaling creates channels as needed. You don't need to create them in advance.
Total channel metadata items1 millionRecommended valueIf you expect to exceed this value, contact support in advance.
Total user metadata items1 millionRecommended valueIf you expect to exceed this value, contact support in advance.
Total locks1 millionRecommended valueIf you expect to exceed this value, contact support in advance.
Message history retention1, 7, 30, 90, or 365 days, or unlimitedDefault limitConfigure this value for each project in Agora Console. Changing the value doesn't affect the retention period of messages that are already stored.

Estimate PCU

Signaling limits and billing are based on PCU, but application metrics often use daily active users (DAU), room count, or class count. Use the formula that matches your application:

Application typeAvailable dataPCU estimate
Instant messaging (IM) or socialDAU and average daily hours onlinePCU ≈ DAU × average daily hours online ÷ 24 × peak factor
Live streamingSimultaneous rooms and average viewers per roomPCU ≈ simultaneous rooms × average viewers per room × peak factor
Education or meetingsSimultaneous classes and attendees per classPCU ≈ simultaneous classes × attendees per class
GamesConcurrent players (CCU)PCU ≈ CCU

The peak factor scales daily averages to peak periods. A value of 2 to 3 is a common starting point. For a known peak event, such as a sale, a tournament, or the start of a school term, use the expected event peak instead of a daily average.

When you estimate PCU, avoid the following common errors:

  • Counting users instead of connections: Each connection counts separately. A user who signs in on a phone and in a browser counts as two PCU.
  • Ignoring heartbeatInterval: A longer heartbeat interval delays offline detection, which can increase the reported PCU. The default is 5 seconds, and the range is 5 to 1,800 seconds.

Channel-level limits

Channel-level limits cover how many users and resources a single channel can hold, and how many messages per second it can handle.

Capacity

The following limits apply to a single channel:

LimitValueTypeDescription
Message channel subscribers without PresenceUnlimitedUnlimited countThe channel message rate recommendations still apply.
Message channel subscribers with Presence5,000Recommended valueIf you expect to exceed this value, contact support in advance.
Message channel publishersUnlimitedUnlimited countNot applicable.
Stream channel online users128Fixed limitThe 129th join call fails with an error code. For larger groups, use multiple stream channels or a message channel.
Topics in a stream channelUnlimitedUnlimited countSignaling creates a topic when its first publisher joins and deletes it when its last publisher leaves.
Locks in a channel32Recommended valueIf you expect to exceed this value, contact support in advance.

Channel message rate recommendations

The channel message rate is the total number of messages that all publishers, including clients and RESTful APIs, send to one channel per second. Signaling calculates this rate separately from the client rate limits, so the channel total can exceed the recommendation even when every client stays within its own limit.

The recommended rate depends on the number of concurrent users in the channel. Each additional user increases the fan-out cost of every message, so a larger channel can handle fewer messages per second:

Concurrent users in one channelRecommended channel message rate
Fewer than 1,000200 messages per second
1,000 to 9,999100 messages per second
10,000 or more30 messages per second

When a channel exceeds the recommended rate, the SDK usually doesn't return an error. Instead, latency can increase, messages can be lost, and users might be unable to send or receive messages or might reconnect repeatedly.

When a channel approaches the recommended rate, do the following:

  • Split users across multiple channels, and check each channel against the recommended rates.
  • Use stream channels and topics for frequent, small messages. Keep each stream channel under 128 users.
  • Aggregate messages on your application server, and send the result using the RESTful API to reduce the upstream message count.
  • If you need a higher rate, contact support in advance. Agora can provide a custom increase if it doesn't affect latency or stability.

Client-level limits

The following limits apply to each Signaling client instance. Signaling counts each client separately.

Rate limits

Signaling groups client APIs into operation categories, and each category has its own per-second quota. Methods in the same category share a quota, and categories don't affect each other. For example, 15 calls to getOnlineUsers and 15 calls to getChannelMetadata in the same second don't trigger a rate limit because the two methods belong to different categories. However, 25 calls to getOnlineUsers in the same second do trigger a rate limit.

The SDK doesn't run or queue calls that exceed a quota. Instead, it reports a rate-limit error in its error callback. To handle the error, throttle or retry the call in your application. For details, see Handle exceeded limits.

Operations with dedicated quotas

The following operations have their own quotas:

OperationMethodsQuota per clientTypeDescription
Send messagespublish60 calls per secondDefault limitMessage channel and user channel calls share this quota.
Send topic messagespublishTopicMessage200 calls per second for each stream channelDefault limitEach stream channel that the client joins has a separate quota.
Modify channel metadatasetChannelMetadata, updateChannelMetadata, removeChannelMetadata20 calls per secondDefault limitThese methods share a quota.
Read channel metadatagetChannelMetadata20 calls per secondDefault limitNot applicable.
Modify user metadatasetUserMetadata, updateUserMetadata, removeUserMetadata20 calls per secondDefault limitThese methods share a quota.
Read user metadatagetUserMetadata20 calls per secondDefault limitNot applicable.
Acquire a lockacquireLock10 calls per secondDefault limitNot applicable.

All other operations

Each row in the following table is an independent category with a quota of 20 calls per second. Methods in the same row share that quota.

CategoryMethods
Log inlogin
Renew a tokenrenewToken
Subscribe to a message channelsubscribe
Join or leave a stream channeljoin, leave
Join or leave a topicjoinTopic, leaveTopic
Subscribe to a topicsubscribeTopic
Subscribe to user metadatasubscribeUserMetadata
Get the online users in a channelgetOnlineUsers
Get the channels that a user has joinedgetUserChannels
Set temporary statesetState
Get temporary stategetState
Set a locksetLock
Remove a lockremoveLock
Release a lockreleaseLock
Revoke a lockrevokeLock
Get locksgetLocks
Get historical messagesgetMessages

Connections and instances

The following limits apply to client instances and to the channels and topics that each client uses:

LimitValueTypeWhen exceeded
Signaling instances per client1Fixed limitCreating a second instance fails.
userId length64 ASCII charactersFixed limitInitialization or login fails.
Message channels subscribed to concurrently50Default limitThe 51st subscribe call fails with an error code.
Stream channels joined concurrently10Default limitThe 11th join call fails with an error code.
Topics joined in one channel concurrently8Fixed limitThe 9th joinTopic call fails.
Topics subscribed to in one channel concurrently50Fixed limitThe 51st subscribeTopic call fails.
Publishers subscribed to in one topic64Fixed limitIf you don't pass a users list, the SDK subscribes to up to 64 randomly selected publishers. The client doesn't receive messages from other publishers.

Message specifications

The following limits apply to messages and to the names and queries that messages use:

LimitValueTypeWhen exceeded
Message size in a message channel or user channel32 KBDefault limitSending fails with error code -11010. The size includes the message payload and customType.
Topic message size1 KBDefault limitSending fails with error code -11010. The size is calculated the same way as for message channel messages.
customType length32 ASCII charactersFixed limitSending fails.
Channel name length64 ASCII charactersFixed limitThe call fails. The name must also use the supported character set. See Channel naming.
Topic name length16 ASCII charactersFixed limitThe call fails.
Messages returned by one getMessages call100Fixed limitGet additional messages from the next page.
getMessages query window24 hours or less between start and endFixed limitThe call fails with an error code.

Presence specifications

The following limits apply to Presence:

LimitValueTypeWhen exceeded
presenceTimeout300 seconds by default, with a range of 5 to 300 secondsFixed rangeNo error is returned. The SDK uses the nearest boundary value. For example, a value of 400 seconds takes effect as 300 seconds.
Temporary state key-value pairs per user per channel32 pairsFixed limitsetState fails.
Size of one temporary state value16 KBFixed limitsetState fails.
Temporary state key length32 ASCII charactersFixed limitsetState fails.
Temporary states cached before joining a channel100Fixed limitThe states take effect, and Signaling sends notifications, after the client joins or subscribes to the channel.
Users per getOnlineUsers page100Fixed limitUse nextPage to get additional pages.
Instant notifications before switching to interval mode50 by default, with a range of 8 to 128Default limitWhen the number of online users reaches this threshold, Signaling switches from instant notifications to interval mode. Set this value with Max number of instant event in Agora Console.

Storage specifications

The following limits apply to channel and user metadata:

LimitValueTypeWhen exceeded
Metadata item key length32 ASCII charactersFixed limitThe call fails.
Metadata sets per channel or user1Fixed limitNot applicable.
Metadata items per setUnlimitedUnlimited countThe 16 KB size limit for the set still applies.
Size of one metadata set16 KBDefault limitThe write fails.
Size of one metadata item16 KBDefault limitThe write fails. The item limit and the set limit both apply.

Metadata stays stored after you write it. Destroying a channel or logging out a user doesn't delete it. Delete metadata explicitly when you no longer need it.

Lock specifications

The following limits apply to locks:

LimitValueTypeWhen exceeded
Locks held by one client concurrentlyUnlimitedUnlimited countNot applicable.
Lock TTL10 seconds by default, with a range of 10 to 300 secondsFixed rangeNo error is returned. The SDK uses the nearest boundary value. The TTL starts when the lock holder disconnects. If the holder reconnects before the TTL expires, it keeps the lock. After the TTL expires, the SDK releases the lock and sends an event.
Lock name length64 ASCII charactersFixed limitThe call fails.

RESTful API limits

The following limits apply to the Signaling RESTful APIs:

LimitValueTypeDescription
Total request rate per account1,000 requests per secondDefault limitThe API returns HTTP 429. See Account-level limits.
publish rate per channelNo separate limitNot applicableSignaling counts RESTful API messages and client messages together toward the channel message rate.
publish message size32 KBFixed limitThe request fails.
publish request bodyA serializable stringFixed limitBinary request bodies aren't supported. Encode binary content in Base64 first.
History query rate60 calls per secondRecommended valueRequests above the recommended rate return a quota error.
History messages per call100Fixed limitGet additional messages from the next page.

Plan channel message rates

To estimate the message rate of a channel, use the following formula:

channel message rate ≈ active publishers in the channel × messages sent per publisher per second

Compare the result with the channel message rate recommendations. Estimate the number of concurrent users and the message rate separately: the number of concurrent users determines the fan-out cost, and therefore the recommended rate that applies.

The following table shows example scenarios. When you plan, replace the example values with measurements from your application.

ScenarioExample scaleEstimated rateRecommended rateRecommended approach
IM group chat500 users. During active periods, 5% of users send one message every 10 seconds.500 × 5% ÷ 10 ≈ 2.5 messages per second200 per second (within)Use a message channel. If you enable Presence, plan for the recommended maximum of 5,000 subscribers.
Live stream comments50,000 viewers. 1% of viewers send one message every 5 seconds.50,000 × 1% ÷ 5 = 100 messages per second30 per second (more than 3× over)Aggregate comments on your application server and send no more than 30 messages per second using the RESTful API, or split viewers across channels. Send less frequent, higher-value events, such as gifts, in a separate channel.
Live stream gifts or system notifications50,000 viewers. No more than 5 messages per second.5 messages per second30 per second (within)Use a different channel from comments so that comments can't use up the available rate.
Multiplayer game state synchronization100 players. Each player sends 10 position updates per second.1,000 messages per second200 per second (5× over)Use stream channels and topics. Keep each channel under 128 users and each publisher under 200 messages per second. Subscribe each receiver to only the publishers it needs, up to 64 publishers.
IoT device reports2,000 devices. Each device reports once every 5 seconds.400 messages per second100 per second (4× over)Split the devices across at least five channels, with no more than 400 devices and 80 messages per second in each channel.
Collaborative editing or whiteboard20 users. Each user sends 20 drawing events per second.400 messages per second200 per second (2× over)Use stream channels and topics. Keep topic messages under 1 KB, and combine the drawing events from each 50 ms window into one message before sending.

Keep the following points in mind when you estimate:

  • The activity ratio and per-user frequency affect the result most. Replace the example values with measurements from your application.
  • Each row describes one channel. Check each channel separately against the recommendations. The project-level total upstream rate of 100,000 messages per second still includes every channel. See Project-level limits.

Frequently asked questions

The following questions cover common misunderstandings about Signaling limits.

Handle exceeded limits

How you detect and handle an exceeded limit depends on the type of limit:

Limit exceededHow to detect itRetry?Recommended action
A client category quota. See Rate limits.The SDK reports a rate-limit error in its callback.YesThrottle calls with a queue in your application, then retry with exponential backoff. Don't resend immediately from the callback.
A fixed capacity limit, such as size, length, or count.The SDK reports an error, such as -11010 for an oversized message.NoCorrect the parameter before you call the method again. Check the message size in your application before sending.
A parameter range, such as presenceTimeout or lock TTL.No error is returned. The SDK uses the nearest boundary value.Not applicablePass a value within the documented range. Don't rely on the SDK to adjust out-of-range values.
A channel message rate recommendation.No error is returned. Latency increases sharply, users can't send or receive messages, or users reconnect repeatedly.Not applicableSplit users across channels or use stream channels. Contact support if you need a higher rate.
A project recommendation, such as PCU or total upstream rate.No error is returned.Not applicableIf you expect to exceed the recommendation, contact support in advance.
A RESTful API quota.The HTTP response contains a quota error.YesThrottle requests on your server and retry with backoff.

The following pseudocode shows one retry pattern for a rate-limit error. For the callback that each platform SDK uses, see the API reference for your platform.

send(msg):
  result = rtm.publish(channel, msg)
  if result.error == RATE_LIMITED:
    delay = min(baseDelay * 2^attempt, maxDelay)  // 100 ms to 2 s
    wait(delay)
    attempt += 1
    if attempt < maxAttempts:
      send(msg)
    else:
      report("publish dropped after retries")
  else:
    attempt = 0

Retries alone aren't enough to stay within your quotas. For more reliable results, use a token bucket for each operation category. For example, use a bucket of 60 calls per second for sending messages and a bucket of 20 calls per second for each other category.

Request higher limits

You can request an increase, or discuss capacity planning, for the following limits. Contact support@agora.io or your Agora technical support contact, and include your App ID, expected scale, and launch date.

LimitDefault valueHow to change it
Total RESTful API request rate per account1,000 requests per secondRequest an increase.
PCU per project200,000Contact support before you exceed it.
Total upstream message rate per project100,000 messages per secondContact support before you exceed it.
Message channel subscribers with Presence5,000Contact support before you exceed it.
Channel message rateSee Channel message rate recommendations.Contact support to discuss a custom increase.
Stream channels joined per client10Request an increase.
Message channels subscribed to per client50Request an increase.
publish rate per client60 calls per secondRequest an increase.
publishTopicMessage rate per client per stream channel200 calls per secondRequest an increase.
Message size32 KB for message channels and user channels, 1 KB for topicsRequest an increase.
Metadata set size16 KBRequest an increase.
Locks in a channel32Request an increase.
Total locks per project1 millionRequest an increase.