# net.latency-summary
Turns a run of probe results (ping replies, TCP connect times) into the
figures `ping` prints at the end: sent, received, lost, loss, min/avg/max,
plus a p95 and a jitter figure.
## Shape
- **Input is whole microseconds, `null` for a lost probe**, in the order the
probes were sent. Integers keep all three languages identical and let the
vectors compare exactly; a caller timing with a monotonic clock converts
once (`elapsed.as_micros()`).
- **Loss** is `lost / sent` in basis points, rounded half-up
(`math.round-div`): 1 of 3 lost is 3333, 2 of 3 is 6667, all lost is 10000.
- **avg** is the mean of the received samples, rounded half-up to a whole
microsecond.
- **p95** is the nearest-rank 95th percentile (`stats.percentile`,
`nearest-rank`): the smallest sample with at least 95% of samples at or
below it. It is always a sample that was really seen; for 20 samples it is
the 19th smallest, not the maximum.
- **jitter** is the mean absolute difference between consecutive *received*
samples, in send order, rounded half-up. A lost probe is skipped, not a
break, so `[1000, null, 3000, 2000]` compares 1000 with 3000 and 3000 with
2000. This is the simple "mean deviation of successive round trips", not
RFC 3550's exponentially smoothed interarrival jitter (which needs one-way
transit times and weights recent packets); it is `null` with fewer than two
replies.
- With no replies, min/avg/max/p95/jitter are all `null` and loss is 10000.
## Errors
An empty list (`samplesUs must not be empty`), a negative sample
(`samples must not be negative`), and a sample that is not a whole number or
null (`each sample must be a whole number of microseconds or null`).
Rust callers building on this can use `latency_summary_to_value` and
`latency_summary_from_value`.