WebRTC Metrics
A comprehensive overview of WebRTC statistics, derived calculations, extracted features, and observable signals, to better understand call quality, connectivity, and user experience in rtcStats
Connection setup time (feature)
Connection-level features measuring how long a connection took to establish: iceConnectionTime for the ICE checks, connectionTime for the DTLS handshake that follows.
Description
Connection-level features, extracted per RTCPeerConnection into features_connection.
These features measure how long the connection took to come up, split into its two consecutive phases:
iceConnectionTime- milliseconds for the ICE connectivity checks to find a path (iceConnectionStatefromcheckingtoconnected).connectionTime- milliseconds for the DTLS handshake that secures that path (connectionStatefromconnectingtoconnected).
Two booleans say whether each phase completed at all, and explain a missing duration:
iceConnected- whethericeConnectionStatereachedconnectedat least once.connected- whetherconnectionStatereachedconnectedat least once.
Added together, iceConnectionTime and connectionTime are the setup cost the user waits through after signaling: finding a path, then securing it.
Extracted by the open-source rtcstats-features package into your own database.
Why it matters
"How long does it take to get a call connected" is the setup number everyone asks for, and these two fields answer it while also saying where the time went. A slow iceConnectionTime is a connectivity problem: candidates arriving late, checks timing out against a strict NAT or firewall, or a fallback to TURN. A slow connectionTime on top of a fast iceConnectionTime is a handshake problem instead, on a path that had already been found.
Tracked over time, both are deployment-quality gauges: a jump after a release, in one region, or on one client version points at a regression. Split by selected candidate pair and the relay premium becomes visible, since a relayed path usually costs more ICE time than a direct one. Split by ICE-lite peer and you can compare peer-to-peer setup against connections to your media servers, which normally connect faster.
The booleans matter as much as the durations. A duration is only meaningful when its phase completed, so iceConnected = false or connected = false marks connections that never established: a failure to count separately, not a slow setup to average in.
Typical values
- Good:
iceConnectionTimeunder ~500 ms,connectionTimeunder ~500 ms. - Concerning:
iceConnectionTimeabove ~1000 ms, orconnectionTimebetween 500 and 2000 ms, where users start to feel the wait. - Bad:
connectionTimeabove 2000 ms, oriceConnected = false/connected = false, where the phase never completed. - Either duration can be
NULL: filter on the matching boolean before averaging.
SQL example
Setup-time percentiles over the last 14 days, for connections that established, split into the ICE and DTLS phases:
SELECT
PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY connection.ice_connection_time) AS p50_ice_ms,
PERCENTILE_CONT(0.90) WITHIN GROUP (ORDER BY connection.ice_connection_time) AS p90_ice_ms,
PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY connection.connection_time) AS p50_dtls_ms,
PERCENTILE_CONT(0.90) WITHIN GROUP (ORDER BY connection.connection_time) AS p90_dtls_ms,
COUNT(*) AS connections
FROM "rtcstats-server" AS server
JOIN features_metadata AS metadata ON metadata.dump_id = server.id
JOIN features_connection AS connection ON connection.dump_id = metadata.id
WHERE server.created_at >= NOW() - INTERVAL '14 days'
AND connection.connected -- only connections that reached 'connected'
AND connection.ice_connection_time IS NOT NULL
AND connection.connection_time IS NOT NULL;
The join down from "rtcstats-server" is what makes created_at available (see the master join). Group by DATE_TRUNC('day', server.created_at) to turn the same query into a setup-time trend across those two weeks.
Related features
- DTLS and SRTP - what the
connectionTimehandshake negotiated: role, DTLS version, SRTP cipher. - Configured ICE servers - the STUN/TURN configuration the ICE checks had to work with.
- Selected candidate pair - the path ICE ended up choosing, and the main explanation for a slow
iceConnectionTime. - ICE-lite peer - whether the far side was a media server, which changes what a normal setup time looks like.
- Offer and answer timing - the signaling cost that precedes both phases.
Related observations
- ICE warmup - ICE connected only after a restart, which inflates
iceConnectionTime. - Connection warmup - the connection failed before establishing, which inflates
connectionTime. - Connection failed - it never established at all.
See also
- rtcstats-server feature extraction - the full feature reference.
- How to query rtcstats-server features - SQL recipes including connection-time percentiles.
- MDN: RTCPeerConnection->iceConnectionState
- MDN: RTCPeerConnection->connectionState