const subscription = call.state.callStatsReport$.subscribe((report) => {
const {
datacenter, // The datacenter where this participant is connected to
publisherStats, // Aggregated stats for the publisher, which is the local participant
publisherRawStats, // Raw stats for the publisher, which is the local participant
subscriberStats, // Aggregated stats for the subscriber, which are the remote participants
subscriberRawStats, // Raw stats for the subscriber, which are the remote participants
participants, // Optional stats for individual participants
timestamp, // The timestamp of the stats report
} = report;
// aggregated stats for the publisher
console.log("Publisher Stats:", {
timestamp: publisherStats.timestamp,
totalBytesSent: publisherStats.totalBytesSent,
averageJitterInMs: publisherStats.averageJitterInMs,
averageRoundTripTimeInMs: publisherStats.averageRoundTripTimeInMs,
qualityLimitationReasons: publisherStats.qualityLimitationReasons,
codec: publisherStats.codec,
});
// aggregated stats for the subscriber
console.log("Subscriber Stats:", {
timestamp: subscriberStats.timestamp,
totalBytesReceived: subscriberStats.totalBytesReceived,
averageJitterInMs: subscriberStats.averageJitterInMs,
averageRoundTripTimeInMs: subscriberStats.averageRoundTripTimeInMs,
highestFrameWidth: subscriberStats.highestFrameWidth,
highestFrameHeight: subscriberStats.highestFrameHeight,
highestFramesPerSecond: subscriberStats.highestFramesPerSecond,
});
});
subscription.unsubscribe();
Call Stats Report
This guide explains how to interpret and use the data provided by the call.state.callStatsReport$
observable.
Basic Usage
This hook provides a comprehensive report of the call statistics, including both aggregated and raw stats for the publisher (local participant) and subscriber (remote participants).
By default, this hook will emit a new report every 2 seconds. If you need historic data (for example, plotting charts), you can buffer the reports in your component state.
Reporting interval adjustment
The default reporting interval is 2 seconds, but you can adjust it to suit your needs. Please make sure to set the adjustment before joining the call.
We recommend keeping it greater than 2 seconds to avoid excessive CPU usage.
// to set the stats reporting interval to 3.5 seconds
call.setStatsReportingIntervalInMs(3500);
await call.join();
// to disable stats reporting
call.setStatsReportingIntervalInMs(0);
Subscribing to individual participant stats
In addition to the aggregated stats, you can also subscribe to stats for individual participants. This is useful if you want to monitor the performance of specific participants in the call.
To subscribe and unsubscribe to stats for a specific participant, check the example below.
This is an advanced feature and adds additional CPU pressure on the client, so use it only when necessary.
const participants = call.state.participants;
// to subscribe to stats for a specific participant,
const sara = participants.find((p) => p.user_id === "sara");
call.startReportingStatsFor(sara.sessionId);
// to consume the stats for that participant
const callStatsReport = call.state.callStatsReport;
const saraStats = callStatsReport.participants?.[sara.sessionId];
// returns an array of stats for every available layer (q, h, f)
const saraVideoStats = saraStats?.streams.filter(
(s) => s.trackType === SfuModels.TrackType.VIDEO,
);
for (const layer of saraVideoStats) {
console.log("Sara's Video Stats:", {
rid: layer.rid, // The RID of the layer (q, h, f)
bytesSent: layer.bytesSent,
codec: layer.codec,
frameWidth: layer.frameWidth,
frameHeight: layer.frameHeight,
framesPerSecond: layer.framesPerSecond,
jitter: layer.jitter,
qualityLimitationReason: layer.qualityLimitationReason,
});
}
// to stop reporting stats for that participant
call.stopReportingStatsFor(sara.sessionId);