rtcstats-server feature extraction
Every session your rtcstats-server processes is distilled into roughly 100 structured features written to a SQL database, automatically, on your own infrastructure, ready to query across every call.
Every dump that reaches your rtcstats-server is more than a file on disk. As the server processes each session it runs feature extraction: it distills the raw WebRTC traces into roughly 100 structured, typed values (connection setup times, codecs, freeze counts, candidate types, geolocation) and writes them as rows into a SQL database. This happens automatically for every session, on the infrastructure you already run. It is open source, and it is free.
Once the data is in SQL, you are no longer limited to looking at one session at a time. You can ask questions across all of your sessions: how call setup time changed after a deployment, what share of calls relayed through TURN last week, which browser version regressed on video freezes. This is the difference between "upload a dump, see what happened" and "run the server, get cross-session intelligence."
The extraction logic lives in the open-source rtcstats-features package. Its features.md is the authoritative, always-current list of every feature and how it is derived. This page is the reference for what those features mean and how to reach them from the KB.
The three levels
Features are extracted at three levels, mirroring how a WebRTC session is actually structured. A session has one client, one or more connections, and zero or more tracks per connection. Each level maps to its own database table:
(one row per dump)"] M["features_metadata
(one row per dump)"] C["features_client
(1 per session)"] N["features_connection
(1..N per session)"] T["features_track
(0..N per connection)"] S -->|"id = dump_id"| M M -->|"id = dump_id"| C M -->|"id = dump_id"| N N -->|"id = connection_id"| T
- Client (one per session): the browser and device,
getUserMediaandgetDisplayMediausage, device enumeration, the upload WebSocket. - Connection (one or more per session): each
RTCPeerConnection, its DTLS and ICE setup, configured ICE servers, the selected candidate pair, lifetime averages, geolocation. - Track (zero or more per connection): each media track, its codec, resolution, quality limitation, freezes, jitter buffer, encoder and decoder.
The SQL cookbook shows how to join these tables back into a whole session.
What you can do with it
- Monitoring dashboards: daily and weekly calls and minutes, connection success rate, TURN usage.
- Anomaly detection: alert when connection time, freeze rate, or
getUserMediafailures cross a threshold. - Deployment comparison: compare setup time or quality before and after a release.
- Regional analysis: split any metric by the user's or relay's country.
- Business intelligence: feed the tables into your existing BI stack, since they are just SQL.
How this relates to the rtcStats enrichment engine
Feature extraction is the local layer: it runs inside your own rtcstats-server and produces the raw structured facts. The rtcStats enrichment engine is the layer built on top of these facts: observations, deductions, and scores. It is available both on rtcstats.com and as an on-premise enterprise package (the AI summary is a rtcstats.com cloud feature). You can run the extraction layer entirely yourself; the enrichment engine is what rtcStats adds on top.
Feature reference
The tables below group the extracted features. Each group links to its dedicated article. Feature names are shown as they appear in rtcstats-features. The corresponding database columns are snake_case (connectionTime becomes connection_time), so translate accordingly in SQL. The feature list expands over time, so your database explorer is always the final word on what is available.
Client features (features_client)
| Feature group | Fields |
|---|---|
| Session and device metadata | startTime, duration, hardwareConcurrency, deviceMemory, screen, window, reloadCount |
| User agent data | userAgentData |
| getUserMedia | calledGetUserMedia, calledGetUserMediaAudio, calledGetUserMediaVideo, calledGetUserMediaCombined, getUserMediaError, getUserMediaErrorCount, getUserMediaSuccessCount |
| getDisplayMedia | calledGetDisplayMedia, calledGetDisplayMediaAudio, calledGetDisplayMediaVideo, getDisplayMediaErrorCount, getDisplayMediaSuccessCount |
| Device enumeration | enumerateDevicesCount |
| Upload WebSocket | webSocketConnectionTime |
| Track lifecycle | audioEnded, videoEnded, audioShortDuration, videoShortDuration |
Connection features (features_connection)
| Feature group | Fields |
|---|---|
| Session metadata | startTime, duration, closed, numberOfEvents, numberOfEventsNotGetStats, numberOfNegotiations, pendingNegotiationAtEnd, signalingDelay, clockSkew |
| API failures | addIceCandidateFailure, setLocalDescriptionFailure, setRemoteDescriptionFailure |
| Offer and answer timing | setLocalDescriptionDelay, setLocalDescriptionRole, setRemoteDescriptionDelay, setRemoteDescriptionRole |
| Connection setup time | iceConnected, iceConnectionTime, connected, connectionTime |
| DTLS and SRTP | dtlsRole, dtlsVersion, srtpCipher |
| ICE-lite peer | usingIceLite |
| Configured ICE servers | configuredIceServers, configuredIceTransportPolicy, configuredIceServersStun, configuredIceServersTurns, configuredIceServersTurnUdp, configuredIceServersTurnTcp |
| Added and gathered candidates | addedHostCandidate, addedMdnsCandidate, addedSrflxCandidate, addedTurnCandidate, addedNullCandidate, gatheredHostCandidate, gatheredMdnsCandidate, gatheredSrflxCandidate, gatheredTurnCandidate |
| Selected candidate pair | firstCandidatePairLocalAddress, firstCandidatePairLocalProtocol, firstCandidatePairLocalNetworkType, firstCandidatePairLocalType, firstCandidatePairLocalTypePreference, firstCandidatePairLocalRelayProtocol, firstCandidatePairLocalRelayUrl, firstCandidatePairRemoteAddress, firstCandidatePairRemoteType |
| Lifetime averages | averageStunRoundTripTime, averageOutboundBitrate, averageInboundBitrate |
| Geolocation: local | rtcstatsLocationContinent, rtcstatsLocationCountry, rtcstatsLocationCity |
| Geolocation: peer | rtcstatsPeerLocationContinent, rtcstatsPeerLocationCountry, rtcstatsPeerLocationCity |
| Geolocation: relay | rtcstatsRelayLocationContinent, rtcstatsRelayLocationCountry, rtcstatsRelayLocationCity |
Track features (features_track)
| Feature group | Fields |
|---|---|
| Identity | kind, direction, trackIdentifier, startTime |
| Codec | codecMimeType, codecSdpFmtpLine |
| Resolution | commonWidth, commonHeight, minWidth, minHeight, maxWidth, maxHeight |
| Frame counters | frameCount, keyFrameCount, qpSum, nackCount, pliCount, firCount |
| Quality limitation | bandwidthQualityLimitationPercentage, cpuQualityLimitationPercentage, otherQualityLimitationPercentage, qualityLimitationResolutionChanges |
| Encoder and decoder | encoderImplementation, powerEfficientEncoder, decoderImplementation, powerEfficientDecoder, averageEncodeTime |
| Simulcast | rid, encodingIndex |
| Freezes | freezeCount, totalFreezesDuration, framesDropped |
| Jitter buffer | jitterBufferDelay, jitterBufferTargetDelay, jitterBufferMinimumDelay, jitterBufferEmittedCount, averageJitterBufferDelay, totalProcessingDelay, totalAssemblyTime |
| Audio quality | concealedSamples, totalSamplesReceived, concealmentPercentage, insertedSamplesForDeceleration, removedSamplesForAcceleration, decelerationPercentage, accelerationPercentage |
| Advanced: L4S and PSNR | packetsSentWithEct1, packetsReceivedWithEct1, packetsReceivedWithCe, packetsWithBleachedEct1Marking, psnrMeasurements, psnrSumY, psnrSumU, psnrSumV, hasNullVideoDecoder |
Next steps
- How to query rtcstats-server features: the table schema, the master join, and eight ready-to-run SQL recipes.
- Can I query aggregated data across sessions?: the short version, with the five-table overview.
Was this page helpful?