Iperf 2 User Manual

Version 2.2.2 — June 2026 — iperf2 project, derived from NLANR/DAST iperf

1. Introduction ⇧ top

Iperf 2 is a network performance measurement tool that generates and receives TCP and UDP traffic between a client and a server. It measures throughput, latency (one-way delay and round-trip time), jitter, packet loss, and many other metrics at the socket level. All reported byte and packet counts reflect what the socket API observed; they do not include lower-layer protocol header overhead (IP headers, TCP/UDP headers, Ethernet framing, etc.). Its multi-threaded design allows it to scale from Wi-Fi testing to 100 Gbps links with thousands of parallel streams.

A test requires two instances: one running in server mode (-s) to receive traffic, and one in client mode (-c host) to generate and send it. The client and server may be on the same host or on different hosts.

Note: Iperf 2 and iperf3 are completely independent programs. They do not interoperate. See Section 2 for a feature comparison.

2. Iperf 2 vs Iperf 3 ⇧ top

Iperf3 is a separate project hosted at https://github.com/esnet/iperf. Both tools measure network performance but they share no protocol compatibility and have different feature sets.

FeatureIperf 2Iperf 3
Traffic Types
TCP trafficYY
UDP trafficYY
SCTP trafficNY
IPv4YY
IPv6YY
Multicast traffic (including SSM)YN
TCP connect onlyYN
Layer 2 checksYN
Output Options
Human-readable formatYY
JSON outputNY
CSV (basic)YN
Hide IP addresses in outputY (v4 only)N
Client-side server reportsYY
Traffic Profiles
Fair-queue rate limitingYY
Write rate limitingYY
Read rate limiting (TCP)YN
BurstsYY
Isochronous (video) TCP/UDPYN
Reverse rolesYY
Bidirectional trafficYY
Full duplex same socketYN
TCP bounceback w/ optional working load(s)YN
Low duty cycle traffic with server-side statsYN
TCP_NOTSENT_LOWAT with select() (--tcp-write-prefetch)YN
TCP near-congestion / L4S (ECN, DualPI2 awareness)Y (--udp-l4s, --near-congestion)N
UDP L4S support with ECN CE marking statsY (--udp-l4s)N
Concurrent TCP working load(s) alongside UDP/bouncebackY (--working-load)N
Peer version detectionY (-X)N
TCP congestion control algorithm selectionY (-Z / --tcp-cca)Y (-C)
Variable/random packet length distributions (Markov chain)YN
Simulated network delay per flow (TCP_TX_DELAY / SO_TXTIME)Y (--send-delay)N
Port range support (-p m-n)YN
UDP batching via sendmmsg/recvmmsgYN
UDP GSO / GRO pathNY, since iperf3 3.21
Metrics
ThroughputYY
Responsiveness per second (RPS)YN
UDP packets (total / lost)YY
UDP jitterYY
Packet latencies (UDP)YN
Frame / burst latencies (TCP/UDP)YN
Write-to-read latencies (TCP)YN
Network power (latency/throughput)YN
InP — bytes in queues (Little's law)YN
TCP CWNDYN
TCP retriesYY
TCP RTTYY
Send-side write-delay histogramsYN
UDP packets per secondYN
Latency histogramsYN
TCP connect timesYN
ECN CE mark counts (received CE-marked packets)Y (--udp-l4s)N
Other
Multi-threaded parallel testsY (always)Y, since iperf3 3.16
Parallel -P implementationThreadsThreads per stream since 3.16 (processes in earlier versions)
Real-time schedulingYN
-t (time limit) support for serverYN
TAP virtual interface support (--tap-dev)YN
CPU affinityNY
Zero copyNY
IPv6 Flow labelNY
--omit (skip first N seconds)YY
Incr dst/src IP/port with -PYN
Device / interface bindingYY
Source port bindingYY
MPTCP supportNY
Scheduled tx start timeYN
Permit keys (TCP only)YN
Python asyncio framework (flows/)YN
Scaling to 1000+ threadsYN/A

3. Installation ⇧ top

Building from Source

Iperf 2 uses the standard GNU autotools build system:

./configure
make -j
sudo make install

The binary is placed in src/iperf before installation. On most distributions iperf 2 is also available as a package named iperf (not iperf3).

Configure Flags

--enable-professional
Enable the professional feature set. Currently enables UDP L4S support (Prague congestion control, --udp-l4s) and tags the version string with the professional branch label. On the udp-l4s git branch, L4S support is on by default; on other branches, this flag is the opt-in.
--enable-fastsampling
Enable higher-precision interval reporting, including four-digit timestamp precision (e.g. 1.0000 seconds). Useful for sub-millisecond -i report intervals.
--enable-thread-debug
Enable asserts and advanced threading diagnostics. See Section 10.
--enable-udp-l4s
Enable UDP L4S support independently of --enable-professional. Enabled by default on the udp-l4s git branch.
--disable-write-select
Disable the select() call before writes. Can improve UDP performance at very high packet rates.
--enable-summing-debug
Enable interval summing diagnostics for debugging parallel stream aggregation.

4. Synopsis ⇧ top

iperf -s [options]
iperf -c server [options]
iperf -u -s [options]
iperf -u -c server [options]

5. General Options ⇧ top

These options apply to both server and client.

-b, --bandwidth n[kmgKMG][,stdev] | npps
Set the target bandwidth. Supports bits/sec (default) or packets/sec (pps suffix). Setting -b 0 disables rate limits (useful for UDP capacity testing). On the server, limits read rate (TCP only). Supports variable loads as mean,stdev drawn from a log-normal distribution, e.g. -b 100m,10m.
-e, --enhanced
Display enhanced output in reports. Provides all available metrics (write counts, retries, CWND, RTT, NetPwr, PPS, etc.) instead of the legacy 2.0.5 format.
-f, --format [abkmgBKMG]
Format for reported values: adaptive, bits, Bytes, kbits, mbits, gbits, KBytes, MBytes, GBytes.
-h, --help
Print a help synopsis.
--hide-ips
Obscure IP addresses in output (useful when publishing results). IPv4 only.
-i, --interval <t | f>
Report interval in seconds (default), or per frame/burst when f is given. Frame interval reporting is experimental. Combine with --enable-fastsampling for sub-millisecond intervals.
-l, --len n[kmKM]
Read/write buffer size (TCP default 128K, UDP default 1470 bytes). Also supports Bra-ket notation for Markov chain packet length distributions. See Bra-ket Notation.
--l2checks
Perform layer 2 length checks on received UDP packets. Requires packet socket support (Linux only).
-m, --print_mss
Print TCP maximum segment size.
--NUM_REPORT_STRUCTS count
Override the default shared memory size (5000) between traffic and reporter threads. Increase if you see "reporter thread too slow" warnings on >1 Gb/s networks.
--omit n
Omit the first n seconds of samples from the final report (TCP only).
-o, --output filename
Redirect report and error output to a file.
--permit-key[=value]
Set a shared key that the server and client must both present for a connection to be accepted. TCP only. See server and client option sections for details.
-p, --port m[-n]
Set server listen port or client destination port (default 5001). Supports port ranges (e.g. -p 6002-6008). See Port Ranges.
--set-rand-seed n
Set the random number generator seed to n for reproducible variable-load tests.
--send-delay n
Simulate network delay on the socket using TCP_TX_DELAY or SO_TXTIME. Units are milliseconds. Requires the FQ packet scheduler. See send-delay Notes.
--sum-dstip
Aggregate parallel traffic threads by destination IP (default is source IP).
--sum-only
Display sum reports only; suppress per-thread reports. Useful with large -P values.
-t, --time n
Duration for listening, receiving, or sending traffic (seconds).
-u, --udp
Use UDP instead of TCP.
--utc
Use Coordinated Universal Time (UTC) in timestamp outputs.
-w, --window n[kmKM]
Set the TCP window size (socket buffer size).
-z, --realtime
Request real-time scheduler priority, if supported by the OS.
-B, --bind host[:port][%dev]
Bind to a specific IP address, optional port, and optional network device. See Binding Notes.
-C, --compatibility
Compatibility mode for older iperf versions; suppresses extra exchange messages.
-M, --mss n
Set TCP maximum segment size via TCP_MAXSEG.
-N, --nodelay
Disable Nagle's algorithm (set TCP_NODELAY).
-v, --version
Print version information and quit.
-x, --reportexclude [CDMSV]
Exclude report types: Connection, Data, Multicast, Settings, Version.
-y, --reportstyle C|c
Report results as CSV (comma-separated values).
--tcp-cca, -Z, --tcp-congestion algo
Set the TCP congestion control algorithm. Requires setsockopt TCP_CONGESTION support. Available algorithms depend on the OS (see sysctl tcp_allowed_congestion_control). May require root.

6. Server Options ⇧ top

Start the server with iperf -s (TCP) or iperf -s -u (UDP).

-s, --server
Run in server mode. The server listens for connections from clients.
-1, --singleclient
Process only one client at a time (serialize connections).
-b, --bandwidth n[kmgKMG]
Limit the server read rate to n bits/sec (TCP only).
-t, --time n
Time in seconds to listen for new connections and/or receive traffic. Defaults to infinite. Recommended for multicast and --no-udp-fin.
--histograms[=binwidth[u],bincount,[lowerci],[upperci]]
Enable latency histograms for UDP packets, TCP writes (with --trip-times), isochronous traffic, or bounceback. Default: 1 ms bin width, 1000 bins, 5%/95% confidence intervals. Append u for microseconds, m for milliseconds.
--jitter-histograms[=binwidth]
Enable jitter histograms for UDP. Optional bin width in microseconds (default 100 μs).
--permit-key[=value]
Require clients to present a matching permit key. If no value is given, the server auto-generates one and displays it in the settings report. Key lifetime is set with --permit-key-timeout (default 20 s). TCP only.
--permit-key-timeout n
Set the permit key lifetime in seconds. Zero disables the timer.
--recv-mmsg #[1–1024]
(Server only, Linux only) Use the recvmmsg(2) syscall to receive # UDP datagrams per call. Reduces per-datagram syscall overhead at high packet rates. Requires -u. The Read column in reports shows actual recvmmsg syscall counts; PPS / Read gives average datagrams per call. See sendmmsg/recvmmsg Examples.
--recv-mmsg-wait-all
Pass MSG_WAITALL to recvmmsg(2), blocking until the full burst is received. Use with --recv-mmsg.
--recv-mmsg-time #
Set the recvmmsg(2) timeout in milliseconds. Use with --recv-mmsg.
--recvlowat #[bytes]
Set SO_RCVLOWAT in bytes. The kernel will not wake the application until at least this many bytes are in the receive buffer. Reduces wake-ups when used with --recv-mmsg.
--skip-rx-copy
Set MSG_TRUNC on recv calls to discard received bytes, reducing CPU load on the receiver.
--tap-dev dev
Receive traffic on the specified TAP virtual interface.
--tcp-rx-window-clamp n[kmKM]
Set TCP_WINDOW_CLAMP in bytes.
--test-exchange-timeout n
Maximum wait time in seconds for the client-server test exchange (default 60 s). Zero disables.
--tos-override val
Set the IP_TOS value for reverse or full-duplex traffic on the server side. Useful for simulating network bleaching of the TOS byte on the return path.
--tcp-cca
Override the client's congestion control algorithm selection (same as --tcp-congestion).
--working-load
Enable support for concurrent TCP working loads alongside UDP traffic streams.
--working-load-cca
Set the CCA for TCP working loads (overrides client-side setting).
-R, --remove
Remove the IPerfService on Windows. (Note: on the client, -R means --reverse; these are distinct uses of the same flag.)
-D, --daemon
Run the server as a daemon. On Windows, installs and runs as IPerfService.
-H, --ssm-host host
Set the source host IP address for source-specific multicast (SSM), i.e. the S in (S,G).
-U, --single_udp
Run in single-threaded UDP mode.
-V, --ipv6_domain
Enable IPv6 reception by setting the domain and socket to AF_INET6 (can receive on both IPv4 and IPv6).

7. Client Options ⇧ top

Start the client with iperf -c server.

-c, --client host[%dev]
Run in client mode, connecting to host. The optional %dev uses SO_BINDTODEVICE to force traffic out a specific interface (requires root).
-b, --bandwidth n[kmgKMG][,stdev] | npps
Set target bandwidth (default 1 Mbit/s) or packets per second. Supports mean,stdev for variable loads. Use -b 0 for unlimited / capacity-seeking (TCP or UDP).
-t, --time n | 0
Duration in seconds to transmit traffic. Zero means run forever (default 10 s).
-n, --num n[kmKM]
Number of bytes to transmit instead of a time limit.
-P, --parallel n
Number of parallel client threads.
-r, --tradeoff
Bidirectional test: client-to-server first, then server-to-client.
-d, --dualtest
Bidirectional test using two simultaneous unidirectional sockets.
-R, --reverse
Reverse the traffic flow (server sends to client). Useful for testing through NAT firewalls. See Reverse & Full Duplex.
--full-duplex
Run full-duplex traffic (transmit and receive) on the same socket simultaneously.
--send-mmsg #[1–1024]
(Client only, Linux only) Use the sendmmsg(2) syscall to send # UDP datagrams per call. The sender always fills the array fully before issuing the syscall, yielding a dramatic reduction in syscall overhead. The Write column shows actual sendmmsg syscall counts; PPS / Write gives average datagrams per call. Requires -u. See sendmmsg/recvmmsg Examples.
--trip-times
Enable end-to-end write-to-read latency measurements. Requires synchronized clocks on client and server. See Clock Synchronization.
--tcp-write-times
Measure socket write times (select + write latencies).
--tcp-write-prefetch n[kmKM]
Set TCP_NOTSENT_LOWAT and use event-based writes via select().
--tcp-quickack
Set TCP_QUICKACK on the socket.
--bounceback[=n]
Run a TCP bounceback / responsiveness test. The client sends small writes (default 100 bytes, 10 per period) and times the round-trip. Results show responses per second (RPS) and latency. See Bounceback Notes.
--bounceback-hold n
Request the server to insert a delay of n milliseconds between its read and write.
--bounceback-no-quickack
Request the server not set TCP_QUICKACK during bounceback (disables TCP ACK delay suppression).
--bounceback-period[=n]
Schedule client sends every n seconds (default 1 s). Zero means continuous back-to-back.
--bounceback-request n
Set the bounceback request size in bytes (default 100).
--bounceback-reply n
Set the bounceback reply size in bytes (default: same as request). Supports asymmetric sizes.
--bounceback-txdelay n
Delay n seconds between the start of the working load and the bounceback traffic.
--burst-period n
Set the burst period in seconds (default 1 s). Intended for low duty-cycle burst traffic.
--burst-size n
Set the burst size in bytes (default 1M).
--connect-only[=n]
Perform only TCP connects (3WHS) without data transfer. Useful for measuring connect times. Optional n is the total number of connects (zero = forever).
--connect-retry-time n
Application-level retry duration in seconds for failed TCP connects.
--connect-retry-timer n
Minimum time in seconds between TCP connect retries.
--dscp
Set the DSCP field (6 bits, masking ECN) in the IP TOS byte. See IP TOS / DSCP.
--fq-rate n[kmgKMG]
Set a fair-queue socket pacing rate (SO_MAX_PACING_RATE) in bytes or bits per second.
--fq-rate-step n[kmgKMG]
Step the fq-rate by n per interval (see --fq-rate-step-interval).
--fq-rate-step-interval n
Time in seconds between fq-rate steps (default 1 s).
--histograms[=binwidth[u],bincount,[lowerci],[upperci]]
Enable select()/write() histograms with --tcp-write-times or --bounceback. Default: 100 μs bin width, 10000 bins, 5%/95% CI.
--ignore-shutdown
End the test on the final write rather than waiting for TCP FIN/FIN-ACK drain.
--incr-dstip
Increment the destination IP for each parallel thread (-P) or port range.
--incr-dstport
Increment the destination port for each parallel thread or port range.
--incr-srcip
Increment the source IP for each parallel thread or port range.
--incr-srcport
Increment the source port for each parallel thread (requires -B to set source port).
--ipg n
Set the inter-packet gap to n seconds. For packets or within a burst when --isochronous is set.
--isochronous[=fps:mean,stdev]
Send isochronous traffic: fps frames per second with load drawn from a log-normal distribution parameterized by mean and stdev. Default: 60:20m,0. Supports packet-count bursts with the p suffix, e.g. 2:25p = two 25-packet bursts per second.
--local-only[=1|0]
Restrict traffic to the local network via SO_DONTROUTE.
--near-congestion[=n]
Enable TCP write rate limiting based on sampled RTT. The delay multiplier defaults to 0.5. Experimental; best used on controlled test networks.
--no-connect-sync
Disable the default synchronization barrier that ensures all parallel threads (-P) complete their TCP connects before any begin sending.
--no-udp-fin
Skip the UDP final server-to-client exchange. Highly recommended to set -t on the server when using this option.
--permit-key[=value]
Present a permit key that must match the server's value. TCP only.
--sync-transfer-id
Pass the client's transfer ID(s) to the server so both display the same ID in their reports.
--txdelay-time n
Delay n seconds after TCP connect and before the first write. For UDP, delay between thread start and first write.
--txstart-time n.n
Schedule traffic to start at a specific Unix epoch time (microsecond resolution). Example: --txstart-time $(expr $(date +%s) + 1).$(date +%N)
--udp-l4s
Run an L4S (Low Latency Low Loss Scalable Throughput) traffic load. Requires an iperf 2 server compiled with L4S support.
--working-load[=up|down|bidir[,n]]
Request a concurrent TCP working load alongside the primary traffic. Defaults to bidirectional, 1 stream. Example: --working-load=down,4 uses 4 server-to-client TCP streams. Working load traffic uses IP ToS BE (0x0).
--working-load-cca
Set the CCA for TCP working loads.
-B, --bind ip[:port] | ipv6 -V
Bind source IP address and optional source port. See Binding Notes.
-F, --fileinput name
Read data to transmit from a file.
-I, --stdin
Read data to transmit from stdin.
-L, --listenport n
Port to receive bidirectional test return traffic.
-S, --tos val
Set the IP_TOS byte. Values 2.1.5+ reflect this setting in reverse/full-duplex traffic. See IP TOS / DSCP.
-T, --ttl n
Time-to-live for multicast (default 1).
-V, --ipv6_domain
Set the domain to IPv6.
-X, --peerdetect
Run peer version detection prior to traffic.
-Z, --linux-congestion algo
Set TCP congestion control algorithm (Linux only; synonym for --tcp-cca).

8. Examples ⇧ top

TCP Client (enhanced)

iperf -c 192.168.1.35 -e -i 1
------------------------------------------------------------
Client connecting to 192.168.1.35, TCP port 5001 with pid 256370 (1/0 flows/load)
Write buffer size: 131072 Byte
TCP congestion control using cubic
TOS set to 0x0 (dscp=0,ecn=0) (Nagle on)
TCP window size:  100 MByte (default)
------------------------------------------------------------
[  1] local 192.168.1.103%enp4s0 port 41024 connected with 192.168.1.35 port 5001
      (sock=3) (icwnd/mss/irtt=14/1448/158) (ct=0.21 ms) on 2024-03-26 10:48:47.867 (PDT)
[ ID] Interval        Transfer    Bandwidth       Write/Err  Rtry     InF(pkts)/Cwnd(pkts)/RTT(var)        NetPwr
[  1] 0.00-1.00 sec   201 MBytes  1.68 Gbits/sec  1605/0        73     1531K(1083)/1566K(1108)/13336(112) us  15775
[  1] 1.00-2.00 sec   101 MBytes   846 Mbits/sec   807/0         0     1670K(1181)/1689K(1195)/14429(83) us   7331
[  1] 0.00-10.78 sec  1.18 GBytes   941 Mbits/sec  9674/0        74        0K(0)/1681K(1189)/14424(111) us   8154
ct=TCP connect time (3-way handshake)
Write/ErrSuccessful socket writes / non-fatal write errors
RtryTCP retransmits
InF(pkts)/Cwnd(pkts)/RTT(var)Bytes&pkts in-flight, congestion window bytes&pkts, round-trip time and variance (μs)
NetPwrNetwork power = throughput / RTT

TCP Server (enhanced)

iperf -s -e -i 1 -l 8K
[ ID] Interval        Transfer    Bandwidth       Reads   Dist(bin=1.0K)
[  4] 0.00-1.00 sec   124 MBytes  1.04 Gbits/sec  22249    798:2637:2061:767:2165:1563:589:11669
[  4] 0.00-10.02 sec  1.25 GBytes  1.07 Gbits/sec  227306   9316:22088:21792:7096:22893:17193:6138:120790
ReadsTotal socket reads per interval
Dist(bin=size)8-bin histogram of socket read return sizes. Bins are separated by colons. In this example with -l 8K, bins are 0–1K, 1K–2K, …, 7K–8K.

TCP Server with Trip Times

iperf -s -i 1 -w 4M     # server
iperf -c host --trip-times -e -i 1   # client
[ ID] Interval        Transfer    Bandwidth    Burst Latency avg/min/max/stdev (cnt/size) inP NetPwr  Reads=Dist
[  4] 0.00-1.00 sec  19.0 MBytes   159 Mbits/sec  52.314/10.238/117.155/19.779 ms (151/131717) 1.05 MByte 380.19  781=306:253:129:48:18:15:8:4
Burst LatencyOne-way TCP write()-to-read() latency: avg/min/max/stdev (ms). Requires synchronized clocks.
cnt / sizeNumber of completed bursts / average burst size (bytes)
inPAverage bytes in-flight (Little's law). See Little's Law.
NetPwrNetwork power = throughput / one-way latency

TCP Client with Clock Sync Check (-X --trip-times)

iperf -c 192.168.1.4 -X -e --trip-times -i 1 -t 2
[  1] Clock sync check (ms): RTT/Half=(3.361/1.680) OWD-send/ack/asym=(2.246/1.115/1.131)
[  1] local 192.168.1.1%ap0 port 47466 connected with 192.168.1.4 port 5001 (MSS=1448) (trip-times)

The clock sync check line shows the estimated RTT, half-RTT, one-way delays, and asymmetry. A large asymmetry value indicates the clocks may not be well-synchronized.

UDP Client (enhanced)

iperf -c <host> -e -i 1 -u -b 10m
[ ID] Interval        Transfer     Bandwidth      Write/Err  PPS
[  3] 0.00-1.00 sec  1.19 MBytes  10.0 Mbits/sec  852/0      851 pps
[  3] 0.00-10.00 sec  11.9 MBytes  10.0 Mbits/sec  8504/0      850 pps
[  3] Server Report:
[  3] 0.00-10.00 sec  11.9 MBytes  10.0 Mbits/sec   0.047 ms    0/ 8504 (0%)
      0.537/0.392/23.657/0.497 ms  850 pps  2329.37
Write/ErrSuccessful socket writes / non-fatal write errors
PPSTransmit packet rate (packets per second)
Server ReportJitter (ms), lost/total datagrams (%), latency avg/min/max/stdev (ms), PPS, NetPwr

UDP Server with Trip Times

iperf -s -i 1 -w 4M -u
[ ID] Interval        Transfer     Bandwidth        Jitter   Lost/Total
      Latency avg/min/max/stdev PPS  inP NetPwr
[  3] 0.00-1.00 sec  44.5 MBytes   373 Mbits/sec   0.071 ms 52198/83938 (62%)
      75.185/2.367/85.189/14.430 ms 31854 pps 3.64 MByte 620.58
LatencyEnd-to-end latency avg/min/max/stdev (ms). Requires --trip-times on client and synchronized clocks.
PPSReceived packet rate
inPBytes in progress (Little's law)
NetPwrNetwork power = throughput / latency

Isochronous UDP (video simulation)

iperf -c 192.168.100.33 -u -e -i 1 --isochronous=60:100m,10m --realtime   # client
iperf -s -e -u --histograms=100u,2000 --realtime                             # server
# Note: --udp-histogram is a legacy alias for --histograms on the server
# Client interval report:
[ ID] Interval        Transfer     Bandwidth      Write/Err  PPS  frames:tx/missed/slips
[  3] 0.00-1.00 sec  12.0 MBytes   101 Mbits/sec  8615/0     8493 pps   62/0/0

# Server summary:
[  3] 0.00-9.98 sec   120 MBytes   101 Mbits/sec   0.010 ms  196/85867 (0.23%)
      0.665/0.083/1.318/0.284 ms 8585 pps  18903.85  601/1
[  3] T8(f)-PDF: bin(w=100us):cnt(85671)=... (5.00/95.00%=3/12,...)
[  3] F8(f)-PDF: bin(w=100us):cnt(598)=...  (5.00/95.00%=17/24,...)
frames:tx/missed/slipsTotal isochronous frames sent / frame IDs not sent / frame slips
T8-PDFLatency histogram for individual packets
F8-PDFLatency histogram for entire frames (bursts)

Markov Chain UDP (variable packet length)

iperf -c 192.168.1.35 -u --len '<256|0.1,0.7,0.2<1024|0.2,0.5,0.3<1470|0.4,0.4,0.2' \
      -i 1 -b 50kpps -e
[  1] 0.00-1.00 sec  45.7 MBytes   383 Mbits/sec  50000/0/0   50000 pps
[  1] 256=256(0,0)|0.100/0.100(11410/0.100) 1024(0,1)|0.700/0.800(79604/0.699)
      1470(0,2)|0.200/1.000(22805/0.200)  113819/500002(22.8%)

The Markov summary lines show each state (packet length), transition probabilities, actual transition counts, and actual vs. configured probabilities. See Bra-ket Notation.

sendmmsg / recvmmsg (batched UDP syscalls)

# Client — batched sending
iperf -c <host> -u --send-mmsg 1024 -b 1Mpps -i 1 -e -l 40
------------------------------------------------------------
Client connecting to <host>, UDP port 5001
Sending 40 byte datagrams, IPG target: 0.00 us (kalman adjust)
Num. of send mmsg array: 1024
------------------------------------------------------------
[ ID] Interval        Transfer     Bandwidth   Write/Err/Timeo  PPS
[  1] 0.00-1.00 sec  14.0 MBytes   118 Mbits/sec   360/0/0  367617 pps
[  1] 1.00-2.00 sec  14.0 MBytes   118 Mbits/sec   359/0/0  367616 pps
[  1] 0.00-10.01 sec   139 MBytes   116 Mbits/sec   3552/0/0  330566 pps

With --send-mmsg 1024, the Write column counts sendmmsg(2) syscalls, not datagrams. PPS / Write = 367617 / 360 ≈ 1022 — the 1024-slot array is nearly full on every call.

# Server — batched receiving
iperf -s -u --recv-mmsg 1024 -e -i 1 -l 40
------------------------------------------------------------
Server listening on UDP port 5001
Num. of recv mmsg array: 1024, wait-all:0, wait time: NULL
------------------------------------------------------------
[ ID] Interval        Transfer     Bandwidth        Jitter   Lost/Total
      Latency avg/min/max/stdev PPS Read/Timeo/NA NetPwr
[  1] 0.00-1.00 sec  14.0 MBytes   117 Mbits/sec   0.001 ms 0/367058 (0%)
      1.830/0.382/3.229/0.766 ms 367058 pps 19688/0/0 8022
[  1] 0.00-10.01 sec   139 MBytes   116 Mbits/sec   0.005 ms 0/3636226 (0%)
      1.846/0.352/3.526/0.775 ms 330566 pps 179667/0/0 7873

The Read column counts recvmmsg(2) syscalls. PPS / Read = 367058 / 19688 ≈ 19: the server can only harvest datagrams already queued in the kernel buffer at the time of the call, so the array fills to roughly 2% of 1024. The sender controls its call timing and always fills the array fully.

Note: In this example, --recv-mmsg 1024 increases average latency from roughly 0.5 ms (without mmsg) to roughly 1.85 ms, because the receiver waits longer for datagrams to accumulate before returning from the syscall. These numbers reflect this specific test environment; actual latency impact will vary. Use --recv-mmsg-wait-all or --recv-mmsg-time to trade latency for higher fill depth.

Bounceback / Responsiveness Test

iperf -c host.domain.com -i 1 --bounceback --permit-key=mytest --hide-ips
[ ID] Interval        Transfer    Bandwidth         BB cnt=avg/min/max/stdev         Rtry  Cwnd/RTT    RPS
[mytest(1)] 0.00-1.00 sec  1.95 KBytes  16.0 Kbits/sec  10=11.949/9.662/19.597/3.127 ms  0  14K/10930 us  83 rps
[mytest(1)] 0.00-10.02 sec  19.5 KBytes  16.0 Kbits/sec  100=10.878/9.651/19.597/1.743 ms  0  14K/11676 us  91 rps
BB cnt=avg/min/max/stdevBounceback count and round-trip latency stats (ms)
RtryTCP retransmits
Cwnd/RTTTCP congestion window and round-trip time
RPSResponses per second

9. Notes ⇧ top

Numeric Suffixes

Many numeric options accept a format suffix character after the value:

SuffixBaseMultiplier
k1031,000
m1061,000,000
g1091,000,000,000
K2101,024
M2201,048,576
G2301,073,741,824

Lowercase suffixes are SI (powers of 10); uppercase suffixes are binary (powers of 2).

Rate Limiting

The -b option limits write rate (client) or read rate (server, TCP only) at the application level. Variable offered loads are supported with the mean,stdev format using a log-normal distribution (e.g. -b 100m,10m). Socket-level pacing via SO_MAX_PACING_RATE is available with --fq-rate and works with --reverse and --full-duplex.

IP TOS / DSCP

Accepted DSCP values include: af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, cs0–cs7, ef, le, nqb, nqb2, ac_be, ac_bk, ac_vi, ac_vo, lowdelay, throughput, reliability, a numeric value, or none.

The ac_xx values map to Wi-Fi WMM access categories per IETF RFC 8325. Setting options:

Clock Synchronization

The --trip-times option requires the client and server system clocks to be synchronized to a common reference. Network Time Protocol (NTP) provides millisecond accuracy; Precision Time Protocol (PTP) provides sub-microsecond accuracy. A GPS-disciplined OCXO is a recommended PTP reference. Clock synchronization errors will directly bias one-way delay measurements.

Iperf 2 can detect large clock synchronization errors during bounceback tests via the three-timestamp check: write(A) < read(B) < read(A). A non-zero error count is reported at the end of the test.

Histograms and Non-Parametric Statistics

The --histograms option captures the full sample distribution rather than just the mean/min/max. This is critical for latency analysis because real network delay distributions are typically non-Gaussian (heavy-tailed).

Reading histogram output:

[  1] 0.00-5.10 sec BB8-PDF:
bin(w=100us):cnt(50)=35:1,37:1,39:1,...,1922:1,3710:1
(5.00/95.00/99.7%=39/1000/3710,Outliers=4,obl/obu=0/0)
BB8-PDFHistogram name (BB8) and type (PDF = raw histogram)
bin(w=100us)Bin width: 100 microseconds
cnt(50)Total samples in this histogram
35:1Bin 35 (3.4–3.5 ms) contains 1 sample
5.00/95.00/99.7%=39/1000/3710Confidence intervals: 5% at bin 39 (3.9 ms), 95% at 100 ms, 99.7% at 371 ms
Outliers=4Samples beyond 3×IQR-equivalent fence
obl/obu=0/0Samples below / above the histogram range

Binding

The -B option binds at layer 3 (IP address + port) using a colon separator. Binding at layer 2 (network device) uses the percent sign as the delimiter.

Warning: Binding a source IP with -B controls the packet source address but does not override routing. If the routing table resolves the destination via a different interface than the -B IP's interface, the packet will exit through the routed interface with the specified source IP. Use -c host%dev or policy routing to control the physical output interface.

Reverse & Full Duplex

--reverse (-R) and --full-duplex each open one socket and use it in full duplex mode. The older -d (dualtest) and -r (tradeoff) open two sockets in opposite directions.

Use --reverse to test through NAT firewalls (the server-side sends, so the outbound connection originates from the client side). Note that NAT firewall piercing may be needed for -d and -r.

Rate limiting with --reverse: The behavior of -b differs by protocol. For TCP with --reverse, -b limits the server's read rate (because TCP has flow control and the read side can regulate the sender). For UDP with --reverse, -b applies on the transmit side, because UDP has no flow control and rate limiting must happen at the sender.

Bounceback

The bounceback test measures network responsiveness in responses per second (RPS) — essentially the inverse of round-trip latency. The client sends small writes (default 100 bytes, 10 per second) and waits for the server to echo them back. Both TCP_NODELAY and optionally TCP_QUICKACK are set to minimize ACK delays. Use --bounceback-hold to insert a server-side processing delay and model more realistic application behavior.

Little's Law / inP

The inP (in-progress) metric applies Little's Law from queuing theory: L = λ × W, where L is the average number of bytes in flight, λ is the arrival rate (writes), and W is the average waiting time. This gives an application-level view of queuing depth — the number of bytes that have been written but not yet read.

Network Power

Network power (NetPwr) is an experimental convenience metric defined as throughput / delay. For TCP transmits, the delay is the sampled RTT. For TCP receives, the delay is write-to-read latency. For UDP, the delay is end-to-end latency. It is not the physics definition of power but a ratio of a desirable property to an undesirable property. Requires -i for TCP (to set the RTT sampling rate).

Multicast

Iperf 2 supports multicast including source-specific multicast (SSM) joins. Caveats: multicast streams cannot use -P (they are serialized by the server). It is strongly recommended to set -t on the server for multicast, because the single end-of-traffic packet from the client may be lost and without a timeout the server thread will hang indefinitely.

Port Ranges

Hyphen notation specifies port ranges: -p 6001-6009 creates one thread per port. Ensure all ports in the range are free. The -P option applies to each destination port within the range. Port ranges work around the Windows limitation where UDP -P > 1 does not dispatch correctly without distinct destination ports.

PPS Calculation

The PPS metric is computed as a derivative: number of packets divided by the elapsed time between the previous last packet and the current last packet — not the sample interval. This means PPS does not necessarily equal (received bytes / interval). With --trip-times, the packet timestamp is taken from the sender's write time, so PPS reflects end-to-end packet rate. Without --trip-times and with -e, PPS reflects receive-side rate only.

send-delay / SO_TXTIME

The --send-delay n option (in milliseconds) simulates per-flow network delay using TCP_TX_DELAY or SO_TXTIME. This requires the FQ (Fair Queue) packet scheduler (tc qdisc). Take care with the FQ queue limits:

tc-fq: limit      (default 10000 packets)
       flow_limit (default 100 packets)

Large delays increase the number of SKBs queued in FQ; packets will be dropped if these limits are exceeded. Using large delays may also trigger TSO auto-defer and sndbuf-limited detection issues.

Fast Sampling

Build with ./configure --enable-fastsampling to enable four-digit timestamp precision (e.g. 1.0000 seconds) in interval reports. Required for -i intervals shorter than 1 ms.

Professional Edition

Build with ./configure --enable-professional to enable the professional feature set, which includes:

On the udp-l4s git branch, L4S support is compiled in by default. On master and other branches, --enable-professional is the opt-in.

Bra-ket Notation (Markov Chain)

Bra-ket notation defines a Markov chain over packet lengths. Format:

<256|0.1,0.7,0.2<1024|0.2,0.5,0.3<1470|0.4,0.4,0.2

Each <n| defines a state (packet length = n bytes). The comma-separated list that follows defines the transition probabilities to each subsequent state. Each row must sum to 1.0. The Markov summary in the output shows the actual transition counts and observed probabilities versus the configured values.

10. Diagnostics ⇧ top

Build with ./configure --enable-thread-debug to enable asserts and advanced thread-level debugging. This is intended for debugging iperf 2 itself, not for production use.

11. Bugs ⇧ top

Report bugs at: https://sourceforge.net/p/iperf2/tickets/

12. Authors ⇧ top

Iperf 2 is based on iperf, originally written by Mark Gates and Alex Warshavsky. Additional contributions from Ajay Tirumala, Jim Ferguson, Jon Dugan, Feng Qin, Kevin Gibbs, John Estabrook, Andrew Gallatin, Stephen Hemminger, Tim Auckland, and Robert J. McMahon (rjmcmahon@rjmcmahon.com).

Source code: http://sourceforge.net/projects/iperf2/

13. See Also ⇧ top

accept(2), bind(2), close(2), connect(2), fcntl(2), getpeername(2), getsockname(2), getsockopt(2), listen(2), read(2), recv(2), recvmmsg(2), select(2), send(2), sendmmsg(2), setsockopt(2), shutdown(2), write(2), ip(7), socket(7), tcp(7), udp(7)

Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition) — W. Richard Stevens, Bill Fenner, Andrew M. Rudoff