Size your WebSocket consumer by events per second, not messages per second, because one message routinely carries several events: measured on the stocks cluster, trade messages averaged 1.85 events each with a maximum of 27 in a single message. A client sized against a messages figure is therefore undersized, and it is the bursts rather than the average that break it.
Applies to
- Plans: every paid subscription.
- Feeds: every channel on wss://socket.massive.com/stocks, /options, /indices, /futures, /forex and /crypto.
- Asset classes: stocks, options, indices, futures, forex and crypto.
One message is not one event
A data message is a JSON array, and the array usually holds more than one event. Measured on the stocks cluster, trade messages carried 1.85 events on average with a maximum of 27 in a single message, and quote messages carried 2.14 on average with a maximum of 26. A consumer sized against a messages-per-second figure will therefore be undersized, and the bursts are what break it rather than the average.
Which channels are heavy
The heavy channels are quotes and, above all, Options Quotes, which is the only feed with a subscription cap, at around a thousand contracts per connection. On the stocks cluster, quotes ran about twice the event rate of trades in one sample, and per-second aggregate bars ran roughly a tenth of either, because one bar replaces every trade in its second. If you need the shape of the market rather than every print, subscribing to AM or A instead of T and Q cuts the volume by an order of magnitude without changing what you can plot.
How to measure what you will actually receive
Do not size a consumer from a published average. Subscribe to the channels you intend to use, during the session you care about, and count for a minute:
- Count messages and events separately. Parse each message as an array and add its length.
- Do it during regular trading hours. An after-hours sample can be an order of magnitude lighter, so it will not tell you whether your consumer survives the open.
- Watch the gap between your read loop and your parser. If the queue between them grows, you are already on the way to a disconnect, well before you see one.
If you see an error
Repeated disconnects with no status message before them usually mean the server-side buffer filled because your client read too slowly. Read packets into a queue immediately and parse them on another thread. If nothing changed on your side, check massive.com/system and massive-status.com for an incident as well.
{"ev":"status","status":"error","message":"not authorized"} after subscribing to a heavy channel is an entitlement or channel-name problem rather than a volume limit.
The one count-based refusal is the Options Quotes cap, which answers {"ev":"status","status":"error","message":"Subscription limit reached for feed..."} and rejects the whole message. Nothing else about the amount of data causes a subscribe to be refused.

