Your Gigabit Link Drops to 200 Mbps. Here’s How to Actually Diagnose It.
You spent the money on fiber. Gigabit router. Cat6a cabling run through the walls. Everything should be fast, right? Then you run a speed test on your phone and it says 200 Mbps. Or maybe your NAS to desktop copy takes an hour when it should take five minutes.
Here’s the thing: speed test apps—especially web-based ones—lie. They measure browser performance, DNS latency, TLS handshakes, and TCP window sizes, not your actual network capacity. And consumer routers? They fudge the numbers. Your ISP’s speed test? Built in a data center thirty miles away with perfect routing.
If you want to know why your network is slow, you need honest tools. You need iperf3 and nload.
iperf3 is a bandwidth measurement tool that cuts through the noise. It creates a direct connection between two hosts and measures throughput with no pretense. nload visualizes real-time traffic on each interface so you can watch the packets flow and spot the moment it all falls apart. Together, they tell you exactly where your bottleneck lives—CPU saturation, MTU mismatch, half-duplex negotiation, buffer bloat, ISP throttling, or just a bad cable.
Let’s dig in.
What iperf3 Actually Does
iperf3 runs in two modes: server (listening for connections) and client (initiating the test). You start an iperf3 server on one machine, then hammer it from another. It measures how many bits per second made the trip.
Here’s the simplest invocation:
# On the server (192.168.1.10)iperf3 -s
# On the client (any other machine on the LAN)iperf3 -c 192.168.1.10The client connects to the server, transfers data for 10 seconds (default), and reports:
Connecting to host 192.168.1.10, port 5201[ 4] local 192.168.1.100 port 54321 connected to 192.168.1.10 port 5201[ ID] Interval Transfer Bitrate[ 4] 0.00-10.00 sec 1.19 GBytes 1.02 GbpsSimple. But that single-threaded test doesn’t tell the whole story. Your NIC has multiple cores, your switch has backplane capacity, and modern TCP can’t always fill the pipe with one connection.
Multi-Stream Testing (When One Flow Isn’t Enough)
Real-world transfers often happen over multiple parallel connections. A browser downloads assets in parallel. A multi-threaded file transfer (like rsync with high thread count) uses multiple streams. Your network should handle this, but sometimes CPU saturation on one of those connections becomes the bottleneck.
Test with multiple parallel streams using -P:
iperf3 -c 192.168.1.10 -P 4This opens four parallel connections and measures combined throughput:
[SUM] 0.00-10.00 sec 4.52 GBytes 3.88 GbpsIf your gigabit link maxes out at 1 Gbps single-threaded but reaches 3.8 Gbps with four streams, your bottleneck is probably TCP window scaling or single-threaded CPU saturation on the server. If it barely improves, you’re hitting a physical limit—switch backplane, NIC buffer, or ISP link.
TCP vs. UDP: Different Questions, Different Answers
By default iperf3 uses TCP, which is what your file transfers, web browsing, and SSH all use. But sometimes you need to measure UDP—VoIP, video streaming, gaming, and real-time traffic all tolerate some loss for lower latency.
Test UDP throughput and jitter:
iperf3 -c 192.168.1.10 -u -b 1GThe -u flag switches to UDP. The -b 1G sets a target bitrate (1 gigabit). iperf3 will try to send at that rate and report what actually got through:
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams[ 4] 0.00-10.00 sec 1.19 GBytes 1.02 Gbps 0.123 ms 0/762939 (0%)That jitter (0.123 ms) tells you how consistent the latency was. Lost datagrams tell you if you’re overflowing buffers. If you’re pushing 1G and losing 5% of packets, something upstream is dropping traffic under load.
Reverse Testing (Test Both Directions)
Your gigabit link might be asymmetric. Maybe the server’s NIC is slower. Maybe there’s traffic saturation in one direction and the switch is favoring downlink. Test the reverse direction with -R:
iperf3 -c 192.168.1.10 -RThis reverses the data flow—the server becomes the sender, the client measures. If forward is 800 Mbps and reverse is 350 Mbps, something’s different about the server’s network path. Check:
- Is the server’s NIC a different model or generation?
- Is the server’s traffic routed through a different switch port?
- Is there asymmetric congestion (e.g., downloads saturate the uplink)?
Time and Bandwidth Control
By default iperf3 runs for 10 seconds. For high-variability networks, that’s not enough to spot drops. For low-bandwidth links, 10 seconds moves barely any data. Use -t to set duration:
iperf3 -c 192.168.1.10 -t 30This runs for 30 seconds. On variable networks, longer tests smooth out the spikes and show you the real minimum throughput.
For rate-limited testing (testing how your NAS handles 500 Mbps instead of max speed), use -b:
iperf3 -c 192.168.1.10 -b 500M -t 30This attempts to send at 500 Mbps and measures how accurately iperf3 can maintain that rate. It’s useful for testing QoS rules or spotting jitter in rate-limited links.
JSON Output for Scripting and Graphing
iperf3 can output results as JSON, so you can graph throughput over time or script automated tests:
iperf3 -c 192.168.1.10 -P 4 -t 30 -J > result.jsonThe output looks like:
{ "start": { "timestamp": { "time": "2026-06-12T12:00:00Z" }, "test_start": { "protocol": "TCP", "num_streams": 4, "target_bitrate": 0 } }, "intervals": [ { "sum": { "start": 0.0, "end": 1.0, "bits_per_second": 980000000.0, "bytes": 122500000 } } ], "end": { "sum": { "bits_per_second": 1020000000.0, "retransmits": 42 } }}Parse this with jq to extract metrics, feed them into Prometheus or InfluxDB, or write it to a CSV for Excel. You can now run daily tests and spot when your network degrades over time.
Real Diagnostic Flow: Finding the Bottleneck
Okay, your gigabit link is slow. Here’s how to narrow it down:
Step 1: LAN-only test (no ISP involved)
Test two machines directly on your local switch, ideally via ethernet (not WiFi):
# Server: 192.168.1.10iperf3 -s
# Client: 192.168.1.100iperf3 -c 192.168.1.10 -P 4 -t 30If this hits gigabit speeds (950+ Mbps on TCP, accounting for protocol overhead), your LAN is fine. Move on.
If it’s slow (say, 300 Mbps), before you blame anything, check:
- Is the server or client running other tasks?
- Is the CPU maxed out (check with
top)? - Are you on WiFi by accident?
Step 2: Switch isolation
If the direct LAN test was slow, test with different switch ports. Disconnect one port, move to another. Some switches have oversubscribed ports or a bad segment. If moving ports fixes it, you found your culprit (that port, that cable, or that switch).
Step 3: Router test
If LAN is fast but crossing the router (testing through your gateway) is slow, the router is your bottleneck. Consumer routers often can’t do line-rate throughput—they’re optimized for latency and concurrent connections, not throughput. Upgrade the router or accept that it’s a bottleneck for LAN-to-WAN traffic.
Step 4: ISP test
If LAN and router are fast but your ISP link is slow, run iperf3 against a server on the internet (linode, digitalocean, anywhere stable). If you hit your ISP’s advertised speed (or close), they’re not throttling you. If you’re way below, it’s ISP, a modem misconfiguration, or bad routing.
Enter nload: Watch It Happen in Real Time
iperf3 gives you aggregate numbers, but sometimes you need to see the traffic flowing. That’s where nload comes in.
nload is a real-time traffic visualizer. Run it in one terminal while iperf3 is running in another:
$ nloadYou’ll see something like:
Device: eth0
Incoming:############################################### 500 Mbps | Avg: 480 Mbps | Min: 120 Mbps | Max: 920 Mbps |
Outgoing:###################################### 400 Mbps | Avg: 410 Mbps | Min: 50 Mbps | Max: 850 Mbps |
Curr: 900 Mbps | Avg: 445 Mbps | Min: 50 Mbps | Max: 920 Mbps | Total: 13.5 GBytes |Watch the bars move. If they spike to max then drop, you’re hitting a ceiling and the kernel is backpressuring. If they’re uneven (one direction much lower), something’s asymmetric. If the “Max” is way lower than expected, you found your ceiling.
nload supports multiple interfaces—cycle through them with arrow keys:
$ nload -mThis shows a dashboard of all interfaces at once. Useful if you’re testing a router or multi-homed server and need to see if traffic is being balanced.
iftop: Per-Host Breakdown
Sometimes the aggregate isn’t enough. You need to know which host is eating the bandwidth. That’s iftop:
sudo iftop -i eth0You’ll see:
192.168.1.100 => 192.168.1.10 850 Mbps 192.168.1.10 => 192.168.1.100 920 MbpsThis shows direction, throughput per connection, and cumulative totals. Useful for finding a rogue host on your LAN, or checking if your NAS is bottlenecking other machines.
bmon: Multi-Interface Dashboards
For a more comprehensive view of all interfaces at once, use bmon:
$ bmonYou’ll see detailed metrics per interface:
┌─────────────────────────────────────────────────────┐│ eth0 ││ RX 580 Mbps TX 620 Mbps Packets 450k RX/410k TX││ Errors: 0 Drops: 0 MTU: 1500 │└─────────────────────────────────────────────────────┘bmon is great for long-term monitoring. It shows you errors, drops, and MTU mismatch symptoms in real time. If the “Drops” counter is climbing, something’s overflowing buffers upstream.
Common Bottleneck Patterns and How to Fix Them
You’ve measured. You’ve visualized. Now what? Here are the patterns you’ll see:
Pattern 1: Full Speed Only in One Direction
You get 950 Mbps downstream but only 200 Mbps upstream.
Most likely cause: TCP window size is too small, or the receiver is slow to send ACKs. The sender gets starved for acknowledgments and throttles back.
Fix: Check the receiver’s CPU (it might be maxed). Increase TCP buffer sizes with sysctl:
sysctl -w net.ipv4.tcp_rmem="4096 131072 67108864"sysctl -w net.ipv4.tcp_wmem="4096 131072 67108864"If the receiver is a slow server, move to a faster one. If it’s your NAS, it might just have a weaker CPU—that’s a hardware limit.
Pattern 2: High Jitter, Packet Loss
You measure high jitter (>5 ms) or consistent packet loss with UDP tests.
Most likely cause: Buffer bloat. Your switch, router, or NIC is overflowing its buffers because traffic comes in faster than it can egress. Packets get dropped.
Fix: Check switch port statistics for errors/drops:
ethtool -S eth0Look for rx_fifo_errors or tx_fifo_errors. High counts mean overflow. Reduce traffic or upgrade the bottleneck (usually the switch or NIC).
Pattern 3: CPU Maxes Out Before Bandwidth
You can only push 400 Mbps even though your link supports gigabit, and top shows CPU at 100%.
Most likely cause: Single-threaded network stack saturation. Your NIC only has one TX queue being used, or the kernel network stack is on one core.
Fix: Enable interrupt coalescing and multi-queue:
ethtool -C eth0 rx-usecs 100Force more RX queues with:
ethtool -L eth0 combined 4(Replace combined with rx or tx if your NIC doesn’t support combined queues.)
If that doesn’t help, the NIC itself might be weak. Upgrading to a 10GbE NIC is expensive but effective.
Pattern 4: MTU Mismatch (PMTU Blackhole)
You get great speeds for small files but transfers hang or drop massively with large files. You’ll see weird behavior where the first few megabytes are fast, then it dies.
Most likely cause: PMTU (Path Maximum Transmission Unit) blackhole. Something on the path (usually a firewall or ISP middlebox) doesn’t fragment packets, drops anything over 1500 bytes, and doesn’t send ICMP “Fragmentation Needed” messages.
Fix: Set your MTU lower:
ip link set eth0 mtu 1460Run iperf3 again. If speed improves dramatically, you found it. Make the change permanent in /etc/network/interfaces or /etc/netplan/.
Pattern 5: Half-Duplex Auto-Negotiate Disaster
Speed degrades wildly, errors spike, and nload shows saw-tooth patterns.
Most likely cause: Old switch or NIC negotiated half-duplex mode instead of full-duplex. This means send and receive can’t happen simultaneously—old 10BaseT behavior.
Check and fix:
ethtool eth0 | grep DuplexIf it says Duplex: Half, force full-duplex:
ethtool -s eth0 autoneg off duplex full speed 1000Make it permanent in ethtool rules or configuration files. If the switch doesn’t support full-duplex (old equipment), replace it.
iperf3 Cheat Sheet
Here are the commands you’ll actually use:
# Basic serveriperf3 -s
# Basic client, 10 secondsiperf3 -c 192.168.1.10
# Four parallel streams, 30 secondsiperf3 -c 192.168.1.10 -P 4 -t 30
# Reverse (server sends, client receives)iperf3 -c 192.168.1.10 -R
# UDP test with 1Gbps target bitrateiperf3 -c 192.168.1.10 -u -b 1G
# Rate-limited to 500 Mbpsiperf3 -c 192.168.1.10 -b 500M
# JSON output for scriptingiperf3 -c 192.168.1.10 -J > result.json
# Bind to specific local IP (useful for multi-homed systems)iperf3 -c 192.168.1.10 -B 192.168.1.100
# Custom port (default is 5201)iperf3 -s -p 6000iperf3 -c 192.168.1.10 -p 6000
# Window size tuning (rarely needed but sometimes helps)iperf3 -c 192.168.1.10 -w 2M
# Interval reporting (show stats every 5 seconds instead of at the end)iperf3 -c 192.168.1.10 -i 5Putting It All Together
Here’s a real diagnostic workflow:
-
Terminal 1: Start nload to watch traffic
Terminal window nload eth0 -
Terminal 2: Start iperf3 server on one machine
Terminal window iperf3 -s -
Terminal 3: Run client test
Terminal window iperf3 -c 192.168.1.10 -P 4 -t 30 -
Watch nload’s bars. Do they hit the ceiling? Stay even in both directions? Show errors?
-
Check iperf3 output. Is it as fast as expected? Are retransmits high?
-
If slow, repeat with reverse flag to test the other direction.
-
If LAN is slow, test different switch ports or move to another switch.
-
If LAN is fast but ISP link is slow, test to an external server.
-
Check
ethtoolstats and system load withtop. -
Adjust MTU, interrupt coalescing, or NIC queues and re-test.
Within an hour, you’ll have narrowed down the bottleneck to a specific component. Then you can either optimize it, accept it as a hardware limit, or replace the culprit.
One More Thing: Monitoring Over Time
If you want historical trending, run iperf3 tests on a schedule and store results in JSON. A simple cron job:
#!/bin/bashDATE=$(date +%Y-%m-%d_%H:%M:%S)iperf3 -c 192.168.1.10 -P 4 -t 30 -J > /var/log/iperf3/test_${DATE}.jsonStick this in a cron job that runs every hour or every day. After a month, you’ll have visibility into whether your network is degrading, or if that slow transfer today was just a fluke.
The Honest Truth
Speed test apps, ISP speed tests, and consumer router dashboards all lie. They measure convenience, not reality. If you want to know why your network is slow—or confirm that it’s not—you need iperf3 and nload.
iperf3 tells you the truth. nload shows you when the truth changes. Together, they’re the difference between blaming your ISP and actually knowing where the problem lives.
Your 2 AM self—the one at the data center trying to troubleshoot why the backup is taking forever—will thank you for knowing these tools.