Speed and throughput tests: iperf3, speedtest, curl
ipconfig and ethtool tell you the link speed the hardware negotiated. That is not the speed you get. These tools measure real throughput to the internet and, more usefully for diagnosing Wi-Fi and cabling, between two machines on your own network.
Link speed is not throughput
A gigabit Ethernet port gives at most about 940 Mb/s of TCP payload; a Wi-Fi link showing 866 Mb/s typically delivers 300 to 500; your internet connection is capped by the ISP and shared with everyone else in the house. Measure in three places to know which limit you are hitting: internet (this page's first section), LAN wired (iperf3), LAN wireless (iperf3 with one end on Wi-Fi). Units: tools report megabits per second (Mb/s, Mbps); file managers show megabytes (MB/s). Divide by 8.
Internet speed from the terminal
# Official CLI (Windows, macOS, Linux): https://www.speedtest.net/apps/cli
speedtest # nearest server, download, upload, latency, packet loss
speedtest -L # list nearby servers
speedtest -s 12345 # a specific server id
speedtest -f json # machine-readable
speedtest --progress=no -f csv
# macOS: brew install speedtest --force (the Ookla tap) or brew install speedtest-cli (the Python one)
# Windows: winget install Ookla.Speedtest.CLI
# Debian/Ubuntu: follow the apt repo instructions on the download page, or: pipx install speedtest-clipip install speedtest-cli # or pipx install speedtest-cli, or apt install speedtest-cli
speedtest-cli
speedtest-cli --simple # ping, download, upload only
speedtest-cli --list | head
speedtest-cli --server 12345
speedtest-cli --secure
speedtest-cli --jsonUnofficial but widely packaged; results are usually close to the official client but can under-read on fast (500 Mb/s+) connections.
# Cloudflare: download a known-size file and time it
curl -o /dev/null -s -w 'speed: %{speed_download} B/s time: %{time_total}s\n' 'https://speed.cloudflare.com/__down?bytes=100000000'
curl -o /dev/null -s -w 'upload: %{speed_upload} B/s\n' -X POST --data-binary @/dev/zero -H 'Content-Length: 50000000' https://speed.cloudflare.com/__up # crude upload test
# Cloudflare's own CLI
npx @cloudflare/speedtest # or: npm i -g @cloudflare/speedtest
# Netflix fast.com
npx fast-cli # or: npm i -g fast-cli; fast --upload
# Windows PowerShell download timing
Measure-Command { Invoke-WebRequest 'https://speed.cloudflare.com/__down?bytes=100000000' -OutFile $env:TEMP\dl.bin }curl -o /dev/null -w '%{speed_download}\n' https://speed.hetzner.de/100MB.bin
wget -O /dev/null https://speed.hetzner.de/100MB.bin # prints an average rate
curl -o /dev/null -w '%{speed_download}\n' --limit-rate 0 -4 https://... # force IPv4 to compare with -6Single-stream HTTP downloads under-read on very fast or high-latency links because one TCP connection cannot fill them; multi-stream tools (Ookla, iperf3 -P) are more accurate for headline numbers, single-stream is more representative of one real download.
Run several times, at different times of day, wired if you can. Wi-Fi results measure your Wi-Fi as much as your ISP. A 4G/5G or satellite link varies minute to minute.
LAN throughput with iperf3
iperf3 sends traffic between two machines you control and reports exactly what the path between them can carry. Run the server on one, the client on the other. Available for every platform: apt install iperf3, dnf install iperf3, brew install iperf3, Windows builds from iperf.fr or winget install iperf3, and as an app on iOS and Android.
# machine A (server), e.g. 192.168.1.10
iperf3 -s
iperf3 -s -p 5201 -D # background daemon
# machine B (client)
iperf3 -c 192.168.1.10 # 10 s TCP test, B → A
iperf3 -c 192.168.1.10 -R # reverse: A → B (tests the other direction)
iperf3 -c 192.168.1.10 --bidir # both directions at once (iperf 3.7+)
iperf3 -c 192.168.1.10 -P 4 # 4 parallel streams (fills fast links)
iperf3 -c 192.168.1.10 -t 30 # 30 seconds
iperf3 -c 192.168.1.10 -i 0.5 # report every half second (shows Wi-Fi variability)
iperf3 -c 192.168.1.10 -u -b 100M # UDP at 100 Mb/s: reports jitter and loss
iperf3 -c 192.168.1.10 -u -b 0 # UDP as fast as possible
iperf3 -c 192.168.1.10 -w 1M # TCP window size
iperf3 -c 192.168.1.10 -6 # IPv6
iperf3 -c 192.168.1.10 -J > result.json
iperf3 -c 192.168.1.10 -M 1400 # MSS: test with smaller segments
iperf3 -c 192.168.1.10 -B 192.168.1.42 # bind to a source address (choose interface)Connecting to host 192.168.1.10, port 5201
[ 5] local 192.168.1.42 port 51230 connected to 192.168.1.10 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 112 MBytes 940 Mbits/sec 0 408 KBytes
[ 5] 1.00-2.00 sec 112 MBytes 941 Mbits/sec 0 408 KBytes
...
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 1.09 GBytes 941 Mbits/sec 0 sender
[ 5] 0.00-10.00 sec 1.09 GBytes 939 Mbits/sec receiver| Result | Meaning |
|---|---|
| ~940 Mb/s, Retr 0 | A healthy gigabit wired path |
| ~94 Mb/s | Something negotiated at 100 Mb/s: a bad cable (one pair broken), an old switch, a port stuck on 100. Check ethtool or the adapter properties |
| ~9.4 Mb/s | 10 Mb/s: a very bad cable or a port in half-duplex; also common through some powerline adapters |
| Retr in the hundreds or thousands | Retransmissions: a lossy link. On wired, a cable or duplex mismatch; on Wi-Fi, interference or weak signal |
| Wildly varying per-second rates | Wi-Fi contention or a powerline link. Use -i 0.5 and watch |
| One direction much slower than the other | Half-duplex or a bad pair affects one direction; also common with cheap USB NICs |
| UDP loss above 0.5% at modest rates | A link that drops packets: VoIP and video calls will suffer |
| 2.3 Gb/s or 9.4 Gb/s | 2.5GbE and 10GbE links; iperf3 may need -P 4 and a fast CPU to fill them |
Public iperf3 servers exist (search "public iperf3 servers") for testing your internet uplink with iperf3 rather than a browser, but the LAN test between two of your own machines is the one that isolates faults.
Wi-Fi specifically
Put the iperf3 server on a wired machine and the client on the Wi-Fi device (or the reverse; test both with -R). Compare with the negotiated rate from netsh wlan show interfaces, wdutil info or iw dev wlan0 link: roughly half is normal, a quarter suggests interference or a poor channel, a tenth suggests a 2.4 GHz connection or a very weak signal. Repeat in each room. Wi-Fi diagnostics →
Latency and bufferbloat
A connection can be fast and still feel slow if latency balloons under load. Test: start a continuous ping to 1.1.1.1, then run a speed test or a large upload. If ping goes from 10 ms to hundreds, the router's buffers are filling (bufferbloat); video calls and games will stutter whenever someone uploads. Fixes are smart queue management on the router (OpenWrt SQM/cake, fq_codel on most modern firmware, "QoS" on consumer routers) or a router that supports it. The Waveform bufferbloat test and flent (Linux) measure it properly; mtr under load shows where the delay appears.
# terminal 1
ping 1.1.1.1
# terminal 2
speedtest # or: iperf3 -c <public server> -R
# watch terminal 1: latency should barely change on a well-managed connectionDisk and USB are often the real limit
Copying files to a NAS or USB drive at 30 MB/s on a gigabit link is usually the drive, the NAS CPU, SMB overhead or a USB 2 port, not the network. iperf3 between the same two machines proves it: if iperf3 reports 940 Mb/s and the copy manages 240 Mb/s, the network is fine.