Rate Limit and Quota
WebSocket Quote Push enforces quota and permission checks based on account, connection, subscribed symbols, subscription types, and quote permissions. Quotas protect the stability of the long-connection service and ensure that users on different permission levels can only subscribe to the market data capabilities they are entitled to.
INFO
The exact quota quantities depend on account type, quote permissions, product plan, market, and category. This document explains how quotas are calculated and how clients should handle them; it does not provide fixed numeric limits. Please refer to your account's actual permissions, API responses, and product configuration.
Quota Types
| Type | Description | Client Recommendation |
|---|---|---|
| Connection Quota | Limits the number of concurrent WebSocket long connections an account or application can hold. When exceeded, new connections, login/auth, or subsequent subscriptions may fail. | Reuse a single connection to carry multiple symbols and multiple data types; avoid opening a separate connection for each symbol. |
| Subscription Quota | Limits the total number of subscription items an account can hold at the same time. A subscription item is usually composed of "symbol + data type"; for K-lines it also includes period and adjustment type. | Send unsubscribe requests promptly when leaving a page, switching symbols, or no longer displaying a certain type of market data, to release quota. |
| Permission Quota | Quote permissions determine whether a market, category, and data depth (such as order book depth, depth book, or broker queue) can be subscribed. | Before subscribing, confirm the user has the corresponding market and quote level enabled; on permission errors, guide the user to upgrade or downgrade the subscription. |
| Rate Limit | The server may rate-limit control messages such as auth, subscribe, unsubscribe, and reconnect. | Batch subscription requests; avoid repeatedly subscribing and unsubscribing the same symbol within a short period. |
Connection Quota
WebSocket is a long-connection capability, and the number of connections itself consumes server resources. Clients should adopt a "few connections, many subscriptions" approach:
- A single business page should preferably reuse one WebSocket connection.
- A single connection can subscribe to multiple symbols and multiple quote types.
- It is not recommended to scale the number of connections linearly with the number of symbols.
- When multiple windows or multiple devices are online at the same time, consider that the account-level connection upper bound is shared.
- After a connection drops, reconnect, log in/authenticate again, and re-subscribe; do not assume the subscription state on the old connection is still valid.
If the client needs to run across multiple pages or processes, manage the connection centrally in the application layer instead of letting each component create its own WebSocket.
Subscription Quota
Subscription quota counts currently active subscription items at the account level. In a single subscription request, different data types consume subscription resources separately, for example:
quote: basic quote subscription.order_book: order book subscription.ticker: ticker / trade tick subscription.kline: K-line subscription, usually further distinguished byperiodandadjustas different subscription items.
The server validates against an account-level total quota internally. This total quota is referred to as uid_total_quota in the backend pipeline, representing the global subscription allowance available to the current user. It is injected from the login state, account permissions, or the upstream gateway; it is not a public request field that clients should fill in or forge.
WARNING
Do not rely on fixed public quota numbers, and do not assume a particular subscription type never counts against quota. Counting rules may differ across environments, permission levels, and server versions — especially whether K-lines count toward the total subscription quota. Always refer to the actual production responses and product rules.
Quota Exceeded Error
When a new subscription would exceed the account's available total subscription allowance, the subscription request fails. If the gateway transparently forwards the subscription response, the common response semantics are:
| Field | Description |
|---|---|
id | Matches the id from the client request, used to correlate request and response. |
code | Result code; 0 indicates success. |
message | Error description. |
When the quota is exceeded, the server may return:
{
"id": "sub-001",
"code": 4,
"message": "sub quota exceeded, max=..."
}Here code = 4 means the subscription quota is insufficient or the maximum subscription count has been exceeded. Upon receiving this error, the client should not retry at high frequency; first reduce current subscription items, or prompt the user to upgrade permissions/plan before retrying.
INFO
A public WebSocket gateway may wrap or translate error responses. Refer to the actual returned fields, but when troubleshooting quota issues, focus on "quota exceeded", "sub quota exceeded", and error code 4.
Order Book Depth and Permissions
order_book subscriptions are constrained not only by the total subscription count but also by the quote permission level. Different markets, categories, and permission levels may return different depths:
- LV1 permission typically only provides basic levels or limited depth.
- Higher permissions such as LV2/LV3 may support more levels or a depth book.
- Some Hong Kong Stock categories may also provide broker queue capability, corresponding to
BROKER_QUEUEpushes. - Without the corresponding market or depth permission, the subscription may fail, or only return lower-level data.
Therefore, the client should not assume it will always receive a full depth book simply because the subscription request includes order_book. The presentation layer should handle the actual pushed content, array length, and missing fields gracefully.
Ticker Batch Push
ticker (trade ticks) may be pushed in merged batches rather than as a separate WebSocket message for each individual trade. The client should process a batch of trade records via the ticker_list array:
- Do not assume a
TICKERmessage contains only one trade. - Deduplicate, sort, or incrementally merge using fields such as
sequenceandtime_ms. - Throttle UI rendering to avoid expensive full redraws on every batch.
- If you need to backfill the latest trades during a disconnection, query the REST ticker API after reconnecting.
Subscribe and Unsubscribe Best Practices
Merge Requests
Whenever possible, merge the symbols and types that need to be subscribed at the same time into a single request. For example, on page initialization, subscribe to the quote of the currently visible list in one request rather than sending a separate subscription request for each symbol.
Subscribe by Visible Range
For large lists, scrolling tables, or watchlist groups, subscribe only to the symbols the current page needs to display:
- When the user switches groups, unsubscribe symbols in the old group that are no longer displayed.
- When the list scrolls, incrementally subscribe and unsubscribe by the visible window range.
- Background pages or hidden tabs can reduce subscription scale, keeping only key symbols when necessary.
Release Quota Promptly
When the user closes a page, switches symbols, unfollows a symbol, or no longer needs a certain type of market data, proactively send unsubscribe:
- Only after a successful unsubscribe is the quota for that subscription item released.
- When the same account still holds the same subscription on another connection or device, the account-level quota may not immediately drop to 0.
- After an abnormal disconnection, the server cleans up the offline session, but the client should not rely on the cleanup delay to release quota.
Avoid Subscription Thrashing
The following behaviors tend to trigger rate limits or cause quota thrashing:
- Re-subscribing to search results on every character the user types.
- Repeatedly subscribing and unsubscribing the same symbol within a short period.
- Multiple connections auto-reconnecting and fully re-subscribing simultaneously when the network is unstable.
- Duplicate subscription requests caused by UI re-renders.
It is recommended to add debouncing, deduplication, and a state machine on the client: only send incremental subscribe or unsubscribe requests when the target subscription set actually changes.
Recover in Batches After Reconnect
After a disconnection and reconnection, you need to log in/authenticate again and restore subscriptions. If the subscription set is large, it is recommended to:
- First restore the symbols currently visible on the page or most critical to the business.
- Then restore the remaining symbols in batches.
- Keep a short interval between batches and handle failed retries.
- Handle quota-exceeded, permission-insufficient, and invalid-symbol errors by category; do not retry indefinitely.
Degradation Strategy
When subscriptions fail or quota is insufficient, the client can degrade by business priority:
- Prioritize keeping the symbols visible on the current screen.
- Prioritize keeping the
quotebasic quote; reduceorder_book,ticker, or multi-periodklinesubscriptions. - When order book depth permission is insufficient, degrade to show available levels or prompt the user to upgrade.
- For low-priority symbols, fall back to low-frequency REST polling.
Troubleshooting Recommendations
When encountering quota or rate-limit issues, troubleshoot in the following order:
- Confirm the WebSocket has completed login/auth.
- Check whether the symbol code, data type, K-line period, and adjustment type in the subscription request are valid.
- Check for duplicate subscriptions, un-unsubscribed items, or quota occupied by multiple pages sharing the account.
- Inspect the
id,code, andmessagein the subscription response, focusing oncode = 4or quota-related hints. - Verify whether the user has the corresponding market, category, and order book depth permissions.
- For bulk subscription scenarios, reduce the batch size and increase retry backoff.