Monitoring quality during a call
Reacting to quality changes
Thenetwork-quality-change event fires whenever Daily’s assessment of the local participant’s network changes. This is the recommended way to drive a quality indicator in your UI — no polling required.
networkState is calculated from packet loss, round-trip time, and available outgoing bitrate, averaged over a ~30-second rolling window. When the state is 'warning' or 'bad', networkStateReasons tells you which metrics are responsible — 'sendPacketLoss', 'recvPacketLoss', 'roundTripTime', or 'availableOutgoingBitrate' — which can help you decide how to respond (for example, prompting a user to check their connection vs. proactively reducing video quality).
In Daily Prebuilt,
'warning' triggers automatic bandwidth reduction and 'bad' disables the local camera. In a custom UI you’re responsible for any adaptive behavior.Getting detailed stats on demand
getNetworkStats() returns a point-in-time snapshot with per-stream bitrates, packet loss, jitter, and RTT — useful if you want to log detailed diagnostics, build an advanced quality panel, or inspect conditions at a specific moment.
stats.latest are updated approximately every two seconds. The object is empty early in the call before enough data has been collected.
Handling connection interruptions
Thenetwork-connection event fires when a connection is established or interrupted. Every call uses two connections — signaling (call management) and sfu (audio/video) — and both reconnect automatically as long as signaling is alive.
Monitoring CPU load
High CPU load can degrade video quality independently of network conditions, particularly on lower-powered devices or in large calls with many incoming video streams. Listen forcpu-load-change to detect this:
cpuLoadStateReason identifies whether encoding, decoding, or scheduling is the bottleneck, so you can target the right response. Use getCpuLoadStats() to poll for per-track decode stats or inspect frame encode/decode times in detail.
Testing quality before joining
Running a pre-call test lets you warn users about poor conditions before they enter a call, or initialize bandwidth settings appropriately.testCallQuality()
testCallQuality() is the recommended pre-call test. It connects to a private Daily room, streams video to Daily’s infrastructure for up to 30 seconds, and returns a verdict based on packet loss, round-trip time, and available bitrate.
Call it after preAuth() or startCamera() and before join():
'good'.
Other pre-call tests
Three additional tests are available for more targeted diagnostics:-
testWebsocketConnectivity()— Checks whether WebSocket connections can be established with Daily’s signaling servers across AWS regions, without requiring a camera or a room. This is the right first check if you’re building for environments where corporate firewalls or VPNs might block WebSockets — a'failed'result here means the call can’t even get started. -
testNetworkConnectivity(videoTrack)— Checks whether a TURN connection can be established with Daily’s infrastructure. A step beyond WebSocket connectivity, useful for stricter network environments. Returns a simple'passed'/'failed'rather than a quality grade. -
testPeerToPeerCallQuality(options)— Returns a quality verdict ('good'/'warning'/'bad') using TURN servers rather than an actual Daily room session. Runs faster (15 seconds by default) and doesn’t require a room URL, but it measures receive-side metrics rather than send-side, and unliketestCallQuality(), it doesn’t seed Adaptive Bitrate for the subsequent call.
Listening for results via event
If you’re building on top of Daily Prebuilt, it runstestCallQuality() automatically in its prejoin UI. You can read the results without calling the method yourself by listening for the test-completed event: