Every v2 event includes two Unix epoch timestamps in microseconds:
detected_time_us: when New Listings Feed detected the source eventsent_time_us: when the endpoint sent the event, after any plan delay
Record a third timestamp as soon as your client receives a message, before parsing or processing it. Keep the client clock synchronized with NTP before comparing it with the server timestamps.
| Measurement | Calculation |
|---|---|
| Detection to publication | sent_time_us - detected_time_us |
| Publication to your client | received_time_us - sent_time_us |
| Detection to your client | received_time_us - detected_time_us |
Detection to publication includes any plan delay. Publication to your client includes server queue and socket-write time, transport, client scheduling, and clock offset. It does not isolate network latency.
Compare many events on the same endpoint, plan, and region. Report p50, p95, and p99 separately, with the event count and observation window. Use detection to your client to compare total observed delivery time across endpoints. Keep missing events and disconnects separate from latency statistics. These are wall-clock estimates, and clock error can produce misleading or negative results.
Record receipt time
ws.on("message", (data) => {
const receivedTimeUs = Math.round(
(performance.timeOrigin + performance.now()) * 1000
);
const event = JSON.parse(data.toString());
if (!("sent_time_us" in event)) return;
console.log({
detectionToPublicationUs: event.sent_time_us - event.detected_time_us,
publicationToClientUs: receivedTimeUs - event.sent_time_us,
detectionToClientUs: receivedTimeUs - event.detected_time_us,
});
});
In the Python client, add the timestamp immediately after recv_data returns:
opcode, raw = ws.recv_data(control_frame=True)
received_time_us = time.time_ns() // 1000
Keep the close-frame and control-message handling. Replace print(message) in the announcement / tweet branch with:
print({
"detection_to_publication_us": message["sent_time_us"] - message["detected_time_us"],
"publication_to_client_us": received_time_us - message["sent_time_us"],
"detection_to_client_us": received_time_us - message["detected_time_us"],
})
The client already imports time. Control messages do not contain event timestamps.