|Technical

RTCP: How Your Phones Already Measure Call Quality

RTCP runs alongside every RTP stream, reporting packet loss, jitter, and round-trip time. What sender and receiver reports contain, and where the data goes.

Every business phone on your network already runs a quality measurement system on every call. It counts lost packets, estimates jitter, computes round-trip time, and often produces a MOS estimate — continuously, passively, using a protocol that has been part of the VoIP standard since the beginning. Most people troubleshooting call quality never look at any of it.

That protocol is RTCP, the RTP Control Protocol, defined in the same document as RTP itself (RFC 3550). This post covers what RTCP actually reports, how its numbers are calculated (and why they differ from what a packet capture or speed test shows), where the reports end up, and how to use them when a quality complaint lands on your desk.

RTP carries the audio, RTCP carries the report card

When a VoIP call sets up, the SDP negotiation allocates a port for RTP — the stream of small, frequent packets carrying encoded audio. By convention, RTP uses an even port and RTCP takes the next odd port up: RTP on 10000, RTCP on 10001. (Modern WebRTC stacks usually multiplex RTCP onto the same port as RTP instead, per RFC 5761, which simplifies NAT traversal — but the port-plus-one convention still dominates desk phones and SIP trunks.)

RTCP is deliberately lightweight. RFC 3550 recommends capping it at 5% of session bandwidth, with a minimum interval of about five seconds between reports (randomized so endpoints don't report in lockstep). On a typical call, each direction produces a quality report roughly every five seconds. That cadence matters later: RTCP gives you a sampled, periodic view, not a per-packet one.

Two report types do most of the work:

  • Sender Reports (SR) come from an endpoint that is actively sending media. An SR contains the sender's wall-clock (NTP-format) timestamp, the corresponding RTP timestamp, and counts of packets and octets sent — plus reception statistics for the streams it's receiving.
  • Receiver Reports (RR) come from endpoints that are only receiving (or are between SRs). They carry the same reception statistics without the sender information.

RTCP also carries SDES items (notably CNAME, a canonical identifier that ties streams together) and BYE packets, but the reception report blocks inside SRs and RRs are where the quality data lives.

What's inside a reception report block

Each report block describes one incoming stream, identified by its SSRC. Five fields matter for quality work.

Fraction lost. An 8-bit fixed-point number: the fraction of packets lost since the previous report, times 256. A value of 26 means roughly 10% loss over the last reporting interval. This is your short-term loss signal — a call that was clean for four minutes and then hit a bad patch shows it here.

Cumulative number of packets lost. A 24-bit running total for the whole stream, defined as packets expected minus packets received. It's a signed value — duplicate packets can push it negative, which surprises people the first time they see it.

Extended highest sequence number received. The low 16 bits are the highest RTP sequence number seen; the high 16 bits count how many times the sequence number has wrapped. This is what makes the "expected packets" arithmetic possible on a 16-bit sequence space.

Interarrival jitter. Covered in detail next, because it's the most misunderstood number in the block.

LSR and DLSR. Two timestamp fields that enable round-trip time measurement without synchronized clocks. Also covered below.

How the RFC 3550 jitter estimator actually works

The jitter number in an RTCP report is not "the variation in packet arrival times" in any raw sense. It's the output of a specific estimator, and knowing how it behaves changes how you read it.

For each pair of packets i and j, the receiver computes the difference in relative transit time:

D(i,j) = (Rj − Ri) − (Sj − Si)

where R is the arrival time at the receiver and S is the RTP timestamp the sender stamped on the packet. Absolute clock offset between the two endpoints cancels out of the subtraction — only the change in transit time survives. If every packet took exactly as long as the last one, D is zero.

The estimator then smooths the absolute value of D with a 1/16 gain, applied on every arriving packet:

J(i) = J(i−1) + (|D(i−1,i)| − J(i−1)) / 16

Each new observation moves the running estimate one-sixteenth of the way toward itself. That's an exponential moving average with a long memory, chosen deliberately by the RFC's authors as a noise-reduction filter.

Two consequences follow. First, a brief jitter spike barely registers. A single packet delayed 100ms in an otherwise smooth stream nudges the estimate up by about 6ms, then it decays back down. The event that made a word drop out may be nearly invisible in the reported number. Second, the reported value is a snapshot, not a mean or a max — it's whatever the estimator read when the report was generated.

This is why RTCP jitter routinely disagrees with other tools. Analyzing a packet capture in Wireshark gives you per-packet interarrival deltas, where you can see the individual 100ms outlier that the estimator smoothed away. A speed test measures neither: it reports throughput on bulk TCP transfers, which says nothing about the timing consistency of small paced UDP packets. And one more unit trap — RFC 3550 jitter is expressed in RTP timestamp units, not milliseconds. For an 8kHz codec like G.711, divide by 8 to get milliseconds; a reported jitter of 160 is 20ms. Some phone GUIs do the conversion for you, some don't, and a misread here is a factor-of-eight error.

If you want the grounding on what jitter and loss actually do to a call, that's covered in Latency, Jitter, and Packet Loss: The Details. This post is about the measurement plane — where those numbers come from.

Round-trip time without synchronized clocks

The LSR/DLSR mechanism is a genuinely elegant piece of protocol design. Here's the problem: two endpoints want to measure round-trip time, but their clocks aren't synchronized and never will be.

The solution: when endpoint A sends a Sender Report, it includes its own NTP-format timestamp. Endpoint B, when it later sends a report back, echoes the middle 32 bits of that timestamp in the LSR (last SR) field and puts the time it held onto it — the delay between receiving A's SR and sending its own report — in the DLSR (delay since last SR) field, in units of 1/65536 of a second.

When A receives the report at time T (by its own clock), the round trip is:

RTT = T − LSR − DLSR

Every term is either measured on A's clock or is a duration B measured locally. B's absolute clock never enters the calculation. No NTP sync, no GPS, no assumptions — just a reflected timestamp and an honest accounting of the turnaround delay.

RTCP-XR: the extended reports

The basic RFC 3550 statistics tell you the network delivered packets late or not at all. They don't tell you what the listener heard, because that depends on what the endpoint's jitter buffer and concealment algorithms did with the damage. RTCP Extended Reports (RFC 3611) close that gap.

RTCP-XR defines several report block types, but the one that matters for voice is the VoIP metrics block (block type 7). It includes:

  • Loss rate and discard rate, separately. Discards are packets that arrived but too late (or too early) for the jitter buffer to use them — invisible to network-level loss counters, but identical to loss from the listener's perspective.
  • Burst and gap metrics: burst density, gap density, burst duration, and gap duration. A burst is a period of high-density loss/discard; a gap is the quiet stretch between bursts. The boundary is set by a parameter called Gmin (16 by default): losses separated by fewer than Gmin received packets belong to the same burst.
  • Round-trip delay and end-system delay — the latter covering the endpoint's own contribution: jitter buffer, codec, and processing delay.
  • Jitter buffer statistics: nominal, maximum, and absolute maximum delay, plus whether the buffer is adaptive.
  • Signal, noise, and echo return loss levels.
  • Quality estimates: an R-factor and MOS scores — MOS-LQ (listening quality) and MOS-CQ (conversational quality, which folds in delay). If you want to build intuition for how R-factor and network impairments map to MOS, our MOS Explorer lets you turn the knobs interactively.

The burst/gap distinction is the most operationally valuable part. Average loss is a misleading statistic: 1% loss spread evenly across a call is nearly inaudible after concealment, while the same 1% concentrated into two three-second bursts makes the caller ask you to repeat yourself twice. Burst density distinguishes these cases; a fraction-lost field averaged over five seconds mostly can't. Understanding VoIP Packet Loss covers why loss distribution matters more than the headline percentage.

Where the reports actually go

RTCP reports are exchanged between the two ends of the media stream, so in the first instance the data lives on the endpoints themselves. In practice it surfaces in several places:

Phone web GUIs. Most business desk phones expose per-call RTCP statistics in their web interface — current call stats on a live call, and often a log of recent calls. This is the fastest place to look when one user complains.

PBX call detail records. Many PBX platforms attach quality statistics to CDRs, or generate separate call quality records alongside them — typically one per call leg.

Provider dashboards. Hosted VoIP providers aggregate RTCP (and XR, where available) from their edge into per-customer quality dashboards. When your provider says "we're seeing packet loss on your side," this is usually the data behind that claim.

SIP PUBLISH collectors. RFC 6035 defines a standard way for endpoints to ship quality summaries off-device: a SIP PUBLISH request with the vq-rtcpxr event package, carrying an application/vq-rtcpxr body summarizing the call's XR metrics. Endpoints can send a session report at call end, interval reports during the call, and alert reports when a metric crosses a threshold. Many desk phone firmwares and PBX platforms support this, feeding centralized quality collectors. If you run more than a handful of phones and aren't collecting these, you're leaving a free monitoring system switched off.

The practical catches

RTCP is genuinely useful, but there are traps.

It fails the same way RTP fails. RTCP flows over UDP on a port adjacent to the media (or muxed with it). The same NAT and firewall problems that cause one-way audio also eat RTCP — sometimes asymmetrically, so one side has statistics and the other reports nothing. An endpoint showing zero RTCP received isn't measuring a perfect network; it's measuring a blocked port.

SBCs terminate and regenerate it. Session border controllers that anchor media typically terminate RTCP on each leg and generate their own reports outward. The statistics your phone sees then describe the path to the SBC, not the end-to-end path. Often that's useful — it localizes problems to a leg — but "the far end reports no loss" may only mean the SBC-to-far-end leg is clean.

Encryption applies here too. When a call uses SRTP, the control channel is protected by its counterpart SRTCP (also RFC 3711). SRTCP makes authentication mandatory and encryption optional per-packet, so on an encrypted call you can't just read quality reports out of a packet capture on a middle hop — you need the stats from a device that holds the keys, i.e., the endpoints or the SBC.

XR is opt-in at both ends. The good stuff — MOS estimates, burst density, jitter buffer discards — only flows if both endpoints implement RFC 3611 and it's enabled in their configuration. Plenty of deployments negotiate plain RTCP only, and plenty of phones support XR but ship with it disabled. If your quality dashboard shows loss and jitter but no MOS or burst data, this is usually why.

Using RTCP when troubleshooting

The practical workflow: when a quality complaint comes in, pull the RTCP statistics from the phone or the PBX before forming a theory. The endpoints were watching the call while it happened; their report blocks tell you whether the problem was loss or late arrival (discards), whether it was bursty or smeared, which direction it affected, and roughly when in the call it occurred. That's enough to decide whether you're chasing a LAN problem, a WAN problem, or a far-end problem — before you've captured a single packet.

Remember the estimator's limits while you read the numbers: smoothed jitter hides short spikes, five-second reporting intervals hide sub-second events, and units may or may not be converted. When the RTCP data points at a timing problem but won't localize it, that's when a targeted packet capture earns its setup cost.

The other half of the workflow is correlation with active testing. RTCP is passive — it can only describe calls that already happened. An active test generates known traffic on demand, so you can reproduce problem conditions and measure them cleanly. If the phones' RTCP history shows bursty loss every afternoon, run a VoIP quality test during the problem window and compare: matching results confirm a network path issue, while a clean active test alongside ugly RTCP numbers points back at the endpoints, their LAN segment, or the far end. Passive reporting tells you something is wrong; active testing tells you whether it's still wrong right now, and from where.

Your phones have been filing quality reports on every call, all along. Start reading them.

Frequently Asked Questions

What is RTCP and how is it different from RTP?+

RTP carries the actual encoded audio of a VoIP call. RTCP (RTP Control Protocol) is the companion protocol defined alongside RTP in RFC 3550. It carries no audio — instead, endpoints exchange periodic sender and receiver reports containing packet loss counts, interarrival jitter, and timing fields used to compute round-trip time.

What is RTCP-XR?+

RTCP-XR (Extended Reports, RFC 3611) adds richer report blocks beyond the basic RFC 3550 statistics. The VoIP metrics block includes estimated MOS scores, R-factor, jitter buffer configuration and discard counts, and burst/gap loss density — a far more complete picture of what the listener actually experienced. Both endpoints must support XR for it to be exchanged.

How does RTCP measure round-trip time without synchronized clocks?+

A sender report carries a timestamp from the sender's own clock. The receiver echoes it back (the LSR field) along with how long it held onto it before replying (the DLSR field). The original sender subtracts both from its current time — all arithmetic happens on one clock, so the endpoints never need to agree on what time it is.

Why do RTCP jitter numbers differ from what Wireshark or a speed test shows?+

RFC 3550 jitter is a smoothed running estimate: each new packet's transit-time variation only moves the value by 1/16 of the difference. Brief spikes barely register, and the reported value is a snapshot at report time, not a maximum. A packet capture can show per-packet deltas; a speed test measures neither.

rtcprtpcall-qualitymosmonitoringvoip-fundamentals

Share

Opens your messaging app. We do not collect or store any phone numbers.
Opens your email client. We do not collect or store any email addresses through sharing.

Want to know when we publish new articles? Sign up for updates