We do not publish a number for Massive's WebSocket latency, and the reason is not evasion: an average measured from our side would describe our network rather than the one your client sits on, and yours is the part that dominates. What we can give you instead is the way to measure your own, which takes a few lines of code and answers the question you actually asked.
Applies to
- Plans: every paid subscription with WebSocket access.
- Feeds: every channel on every cluster under wss://socket.massive.com.
- Asset classes: stocks, options, indices, futures, forex and crypto.
How to measure your own latency
- Subscribe to a busy channel, such as T.* on the stocks cluster, during regular trading hours.
- Measure your own clock offset first, and add it to every latency you compute. On macOS sntp time.apple.com prints it; on Linux chronyc tracking does. This machine was 135 milliseconds behind true time when this was written, which is larger than the latency being measured, so skipping this step produces a figure that is mostly clock error.
- For each event, record your own arrival time the moment your code reads the frame off the socket, before any queue of your own, and subtract the event's exchange timestamp. On the WebSocket that field is t and it is Unix milliseconds on every cluster, including options and futures. REST is the other way round: nanoseconds on trades, quotes, snapshots and futures, and in the flat files, with milliseconds only on REST aggregates.
- Report percentiles, not a mean. One garbage-collection pause will move a mean and tell you nothing about the typical event.
- Re-run it. Two runs on the same machine and network twenty-five minutes apart gave medians of 41 and 9 milliseconds before the offset correction, so a single sample is not a measurement.
We deliberately do not publish a headline figure here. Any number we measured would describe our office network rather than yours, and the two runs above show how far it moves between samples. The procedure is the deliverable.
What the timestamps mean
Stock trades and quotes carry two timestamps and the gap between them is not our latency. pt, the participant timestamp, is when the exchange or reporting facility recorded the event; t is when the SIP published it. The difference is the SIP's own processing, and it sits upstream of Massive. Measuring against pt therefore includes the SIP's delay as well as ours and your network's.
What dominates the delay
Geography dominates. A consumer in the same region as our servers sees a small fraction of the delay a consumer on another continent sees, and no amount of tuning on either side closes that gap. After geography, the next biggest cause is your own read loop: a client that parses in the thread that reads adds its parse time to every event, and under a burst that grows into the same range as the network delay. Read into a queue and parse elsewhere.
If you see an error
Latency that grows steadily over a session is usually a slow consumer, which ends in a disconnect once the server-side buffer fills. Check your socket's receive queue to be sure: if it stays near empty while the latency, taken at the socket read, grows, the events were already late when they reached you, and Why is my Massive WebSocket data running behind, and is it my client or Massive? says what to send us.
A negative latency means your clock is behind the exchange's, not that events arrived before they happened: your machine read an earlier time than the SIP did at the same instant. Correct by adding your measured offset, which makes the true latency larger than the raw figure, not smaller. Fix the clock first; every other number depends on it.

