demo · v141

Stats Lifecycle

When does an outbound-rtp stats object first show up in getStats()? Different browsers answered differently — Safari created it after SDP, Chrome only after first packet, Firefox somewhere in between. Chrome 141 aligns with the W3C answer: stats appear once the SSRC is known via SDP, even before any packets flow. This matters for any conferencing app that polls early.

checking support…

When you call pc.getStats() at each lifecycle point, do you see the outbound-rtp object?

connection event
≤ 140 (chrome)
141+ & spec
addTrack() called
absent
absent
setLocalDescription resolved
absent
present
setRemoteDescription resolved (SDP exchange complete)
absent (chrome only)
present
ICE connected
absent
present
first packet sent
present
present

the polling code

// Conferencing app polls early to populate the bitrate UI
setInterval(async () => {
  const stats = await pc.getStats();
  for (const r of stats.values()) {
    if (r.type === "outbound-rtp") {
      updateBitrateUI(r.ssrc, r.bytesSent);
    }
  }
}, 1000);

// On Chrome ≤140 this loop returned no rows for the first ~second of every call.
// On 141+ rows are present from setLocalDescription onwards.

why this angle

The chromestatus entry frames this as cross-browser alignment. The spec-correct moment to create the stats object is "as soon as SDP says the stream exists" — before any RTP flows. Apps that built bitrate dashboards or quality probes against Chrome's older "wait for packets" behaviour will see entries appear sooner now; apps that assumed the stats matched Safari's earlier model will see consistent behaviour. Either way, polling code that depended on the exact timing needs to be relaxed.

see also

scenario focus

Select a scenario to focus its rendered example and summary.