TCP tells you how much a path can carry. UDP tells you what the path does to traffic that cannot slow down - voice, video, and anything real-time. iPerf3's UDP mode sends at exactly the rate you specify and reports three things TCP never shows you directly: jitter, packet loss, and out-of-order delivery. Every output block below comes from a live Cisco Modeling Labs topology with real routers in the path. This article is part of our complete iPerf guide.
Why UDP Testing Is Different
TCP adapts. When the network drops a segment, TCP retransmits it and slows down, so a TCP test converges on "whatever the path can sustain." UDP does not adapt. iPerf3 sends datagrams at the rate you set with -b, and whatever the network drops stays dropped. That makes UDP the right tool for two jobs: measuring loss along a path (TCP hides loss inside retransmissions), and simulating real-time traffic that behaves the same way.
The server detects loss by sequence numbers in the datagrams and computes jitter continuously, using the smoothed mean of differences between consecutive transit times (the same approach RTP uses per RFC 1889). Your clocks do not need to be synchronized; the math subtracts the offset out.
A Clean UDP Test
The client sends 10 Mbit/sec through two routed hops. Note the -u for UDP and -b for target bandwidth:
client:~$ iperf3 -c 10.0.20.10 -u -b 10M
[ ID] Interval Transfer Bitrate Total Datagrams
[ 5] 0.00-1.00 sec 1.19 MBytes 10.0 Mbits/sec 865
[ 5] 1.00-2.00 sec 1.19 MBytes 10.0 Mbits/sec 863
[ 5] 9.00-10.00 sec 1.19 MBytes 9.99 Mbits/sec 863
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-10.00 sec 11.9 MBytes 10.0 Mbits/sec 0.000 ms 0/8634 (0%) sender
[ 5] 0.00-10.01 sec 11.9 MBytes 10.0 Mbits/sec 0.206 ms 0/8634 (0%) receiver
Read the receiver line: 0 lost out of 8,634 datagrams, 0.206 ms jitter. This path can carry 10 Mbit/sec of real-time traffic cleanly.
What Happens When You Ask for Too Much
Now the same path, but the client pushes 100 Mbit/sec into a path that can only carry about 35:
client:~$ iperf3 -c 10.0.20.10 -u -b 100M
[ ID] Interval Transfer Bitrate Total Datagrams
[ 5] 0.00-1.00 sec 11.9 MBytes 100 Mbits/sec 8646
[ 5] 9.00-10.00 sec 11.9 MBytes 99.9 Mbits/sec 8624
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-10.00 sec 119 MBytes 100 Mbits/sec 0.000 ms 0/86327 (0%) sender
[ 5] 0.00-15.47 sec 84.6 MBytes 45.9 Mbits/sec 0.082 ms 25078/86327 (29%) receiver
The sender happily reports 100 Mbit/sec with zero loss - it measured its own transmit rate, nothing more. The receiver tells the truth: 29% of datagrams never arrived. This is the single most misread iPerf3 output. If you only glance at the sender line, an over-driven UDP test looks perfect while the network is on fire.
Understanding Jitter
Jitter is the variation in packet arrival spacing. If packets leave every 1.4 ms and arrive every 1.4 ms, jitter is zero even if the absolute latency is high. Voice and video codecs buffer against jitter, and their buffers are finite: as a rough guide, keep jitter under 30 ms for voice, and treat anything under a few milliseconds (like the 0.2 ms here) as excellent. High jitter with low loss usually points to queueing - traffic is getting through, but it is waiting in buffers of variable depth along the way (a QoS problem more than a capacity problem; see our QoS guide).
Finding Loss That TCP Hides
Here is the same path with 2% packet loss injected on the WAN link. A TCP test just gets slow, but the UDP test pinpoints the loss rate:
client:~$ iperf3 -c 10.0.20.10 -u -b 20M
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-10.00 sec 23.8 MBytes 20.0 Mbits/sec 0.000 ms 0/17266 (0%) sender
[ 5] 0.00-10.10 sec 23.3 MBytes 19.4 Mbits/sec 0.219 ms 366/17266 (2.1%) receiver
366 of 17,266 datagrams lost - 2.1%, matching the injected 2% almost exactly. When a TCP test is mysteriously slow, a moderate-rate UDP test like this is how you separate "the path is lossy" from "the path is fine but something limits TCP" (we walk that whole decision tree in troubleshooting slow throughput).
UDP Flags That Matter
-b 50MTarget bandwidth. Default is only 1 Mbit/sec, so an unadorned -u test tells you almost nothing. Set it deliberately.-l 1200Datagram size. Keep it under the path MTU so one datagram = one packet; a fragmented datagram counts as lost if any fragment drops. 1200 is safe almost everywhere; the default 1470-byte-class sizing suits plain Ethernet.-P 4Parallel UDP streams, each rate-limited separately by -b. Four streams at 25M approximate four concurrent video calls better than one stream at 100M.-RServer sends, client receives. Loss is often asymmetric; test both directions.-t 60Longer tests catch intermittent loss that a 10-second burst misses.A Practical UDP Test Recipe
- Establish the TCP ceiling first:
iperf3 -c <server>. Say it lands around 35 Mbit/sec. - Run UDP at roughly half that:
iperf3 -c <server> -u -b 15M -t 30. You want loss and jitter on a non-congested path. - Step up toward the ceiling in stages (20M, 25M, 30M) and watch where loss begins. That knee is your usable real-time capacity.
- Only over-drive deliberately (like the 100M test above) when you want to prove where the bottleneck is, not to measure normal behavior.
Key Takeaways
UDP mode measures what TCP conceals: loss, jitter, and reordering. The sender line reports intent and the receiver line reports reality, and they diverge dramatically the moment you exceed path capacity. Set -b deliberately, keep datagrams under the MTU, test both directions, and find the loss knee by stepping the rate up gradually. For TCP-side tuning and everything else iPerf3 can do, head back to the iPerf complete guide.