Diagnosing Slow LAN Transfer Speeds Between Linux Machines With iperf3 in 2026

When I copy a 200 GB file across my home network and watch the progress bar crawl at 4 MB/s, the first question I ask is not “is my disk slow?” It is “is this a network problem, or is something else getting in the way?” That single question is the reason iperf3 exists. In this guide, I will walk you through diagnosing slow LAN transfer speeds between Linux machines with iperf3, from a fresh install to interpreting results and isolating bottlenecks that no other tool exposes as clearly.

I have been using iperf3 on everything from Raspberry Pi home servers to 10GbE NAS rigs, and the pattern of confusion is always the same: people see high iperf3 numbers but low file-copy speeds, or they hit a hard cap at 100 Mbps on a gigabit link. We will fix both.

What Is iperf3 and Why Use It?

iperf3 is a command-line tool for measuring maximum network bandwidth between two endpoints. It uses a simple client-server model: one machine listens on TCP port 5201, the other sends traffic, and you get a precise throughput number at the end of the test.

The reason iperf3 is so valuable for diagnosing slow LAN transfers is that it isolates the network from everything else. When you copy a file with Samba, NFS, or SCP, you are measuring the combined speed of your disks, your CPU, your protocol overhead, and your network. iperf3 removes the disks and the protocol, so any speed problem you find is purely a network problem. That single fact is what makes it the right first step.

iperf3 is maintained by ESnet and is available in the repositories of every major distribution. It is lightweight, has no GUI dependencies, and produces repeatable numbers you can compare over time.

Installing iperf3 on Linux

Installation is straightforward on every mainstream distribution. Run the package manager command that matches your system.

On Debian, Ubuntu, Linux Mint, MX Linux, and Pop!_OS:

sudo apt update && sudo apt install iperf3

On Fedora, RHEL, Rocky Linux, and AlmaLinux:

sudo dnf install iperf3

On CentOS Stream and older RHEL with yum:

sudo yum install iperf3

On Arch Linux and Manjaro:

sudo pacman -S iperf3

On Alpine Linux (common in containers and NAS firmware):

sudo apk add iperf3

Once installed, verify the version with iperf3 -v. You should see something like iperf 3.x printed back. If the command is not found, the package did not install correctly or your PATH is missing /usr/sbin. Try which iperf3 to confirm.

You need iperf3 on both ends of the test. I keep it on every Linux machine I touch because you never know when a slow file copy is going to turn into a debugging session.

Diagnosing Slow LAN Transfer Speeds Between Linux Machines With iperf3

This is the core diagnostic workflow. I run these four steps in order on every slow transfer report, and they catch the problem nine times out of ten.

Step 1: Verify the Link Speed Before Anything Else

The most common reason iperf3 shows disappointing numbers is that the network interface negotiated at the wrong speed. Before running any test, check what your NIC actually thinks it is doing.

Use ethtool on the interface (commonly eth0, enp3s0, or eno1):

sudo ethtool eth0 | grep -E "Speed|Link detected"

If you do not have ethtool, ip link works on any Linux:

ip -s link show eth0

Look for Speed: 1000Mb/s on a gigabit link. If you see 100Mb/s, your cable, switch port, or auto-negotiation is broken. No amount of iperf3 tuning will fix that. Replace the cable first, then re-test.

Step 2: Start the iperf3 Server

Pick one machine to act as the server. I usually pick the machine with the static IP because it is easier to remember. Open a terminal and run:

iperf3 -s

You will see:

Server listening on 5201

That is all. The server runs in the foreground and waits for a client connection. If you want it to run in the background and keep running after you log out, add -D to daemonize:

iperf3 -s -D

Note the server’s IP address with ip -4 addr show. You will need it for the client.

Step 3: Run the Client Test

From the second machine, run a basic test against the server. Replace 192.168.1.50 with your server’s IP:

iperf3 -c 192.168.1.50

By default, the test runs for 10 seconds using a single TCP stream and reports the bandwidth at the end. On a healthy gigabit link between two modern Linux machines, you should see something between 800 Mbits/sec and 940 Mbits/sec. Anything consistently below 700 Mbits/sec means something is wrong.

Step 4: Run a Reverse Test

Network problems are not always symmetric. A bad cable, a faulty switch port, or a duplex mismatch often shows up in only one direction. Run the reverse test with the -R flag:

iperf3 -c 192.168.1.50 -R

Compare the two numbers. If one direction is dramatically slower (say, 940 Mbits/sec one way and 30 Mbits/sec the other), you have found a hardware fault on the slower path.

Interpreting iperf3 Results

After a test completes, iperf3 prints a summary block. The fields that matter for diagnosing slow transfers are these.

Bandwidth: The average throughput during the test. On a 1 Gbps link, expect 700 to 940 Mbits/sec. On 10GbE, expect 7 to 9.4 Gbits/sec. Lower numbers mean a real bottleneck.

Retr (retransmissions): The number of TCP packets that had to be resent. A handful is fine. If you see thousands of retransmissions during a 10-second test, your link is dropping packets, which usually means a bad cable, a noisy environment, or a duplex mismatch.

Cwnd (congestion window): The TCP receive buffer in use during the test. If this number is small relative to the bandwidth-delay product of your link, you have a buffer tuning problem.

What is a good iperf3 score? For a 1 Gbps wired link, anything above 800 Mbits/sec is healthy. For 10GbE, anything above 7 Gbps is healthy. For WiFi 6 at close range, 500 to 700 Mbits/sec is realistic. Anything consistently 30 percent below the link rate is worth investigating.

Verifying Network Interface Speed

Two commands answer the question “what speed is my NIC actually running at?” I run both because they sometimes disagree, and that disagreement is itself a clue.

The first is ethtool, which talks directly to the driver:

sudo ethtool eth0

Look at the Speed, Duplex, and Link detected lines. Full duplex and the expected link speed is what you want.

The second is ip link, which reports what the kernel sees:

ip link show eth0

If ethtool says 1000Mb/s but ip link shows a low packet error count, your driver is doing fine but you are dropping frames somewhere. If ethtool says 100Mb/s, your link negotiated down. Change the cable.

Advanced iperf3 Tests for Deeper Diagnosis

Once a basic test passes, the next layer of commands helps you find problems that only show up under specific conditions.

Parallel streams with -P: Some network paths handle a single long-lived TCP stream poorly because of how intermediate switches buffer traffic. Test with multiple streams:

iperf3 -c 192.168.1.50 -P 4

If four parallel streams give you a much higher total bandwidth than a single stream, you have a buffering problem somewhere along the path.

UDP mode with -u: UDP testing tells you about packet loss and jitter, which TCP testing hides because TCP retransmits silently:

iperf3 -c 192.168.1.50 -u -b 1G

Look at the jitter and lost/total fields. Any non-zero packet loss on a LAN means a real problem.

Longer tests with -t: A 10-second test can miss problems that only appear over time. Run a 60-second test:

iperf3 -c 192.168.1.50 -t 60

JSON output with -J: If you want to log results for comparison over time, ask for machine-readable output:

iperf3 -c 192.168.1.50 -J > result.json

Why iperf3 Speeds Differ From Actual File Transfers?

This is the question I see most often on forums: “My iperf3 shows 900 Mbits/sec, so why does my file copy only hit 200 Mbits/sec?” There are five usual suspects, and you can test for each one.

1. Disk I/O bottleneck. iperf3 does not touch your disks. File transfers do. If your source or destination disk is a slow mechanical drive, a slow SSD, or a busy NAS volume, no network speed will save you. Test disk speed with dd if you want a quick check:

dd if=/dev/zero of=/tmp/testfile bs=1M count=1024 oflag=direct

If the write speed is below your iperf3 number, the disk is your bottleneck.

2. SMB/CIFS protocol overhead. Samba and Windows file sharing add encryption, signing, and per-file metadata calls that iperf3 does not perform. On small files especially, SMB can drop your effective throughput by 50 percent or more. Test with plain FTP or HTTP to compare.

3. CPU bottleneck on the server. Older NAS devices, especially ARM-based ones, cannot encrypt or hash data fast enough to saturate gigabit. Check CPU usage on both machines during a file transfer with top. If a core is pinned at 100 percent, the CPU is your bottleneck.

4. WiFi instead of wired. iperf3 over WiFi can show high peaks but very inconsistent real-world performance. If your file server is on WiFi, plug it in with a cable and re-test.

5. Protocol encryption overhead. SSH, SFTP, and SMB with encryption enabled all require CPU cycles per byte transferred. On a Raspberry Pi, that CPU cost can cap your transfer at 30 to 50 MB/s even on a gigabit link.

Network vs Disk Bottleneck Decision Guide

When a file transfer is slower than you expect, use this decision process to isolate the cause.

Step 1: Run iperf3 -c SERVER_IP. Note the bandwidth.

Step 2: Run a dd write test on both source and destination machines. Note the disk write speeds.

Step 3: Compare the three numbers. The slowest of the three is your bottleneck.

If iperf3 is lowest: It is a network problem. Re-check cables, switch ports, duplex settings, and MTU.

If the disk write on the destination is lowest: Your receiving disk cannot keep up. Common on NAS devices with slow mechanical drives.

If the disk read on the source is lowest: Your source disk cannot feed the network fast enough. Common with HDDs reading many small files.

If CPU usage on either machine is at 100 percent during transfer: Your protocol stack is CPU-limited. Disable encryption, switch protocols, or upgrade the CPU.

This is the workflow I run on every “slow network” report, and it has never failed to identify the real culprit.

TCP Buffer Tuning for High-Speed Links

On 1GbE and slower links, default Linux TCP buffer sizes are usually fine. On 10GbE and faster, they become the bottleneck.

Check your current limits:

sysctl net.core.rmem_max net.core.wmem_max net.ipv4.tcp_rmem net.ipv4.tcp_wmem

For 10GbE, set them to a bandwidth-delay product that makes sense for your network. A reasonable starting point for a local network:

sudo sysctl -w net.core.rmem_max=12582912
sudo sysctl -w net.core.wmem_max=12582912
sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 12582912"
sudo sysctl -w net.ipv4.tcp_wmem="4096 65536 12582912"

To make these persistent across reboots, add them to /etc/sysctl.d/99-network-tuning.conf.

If you want the latest congestion control algorithm, try BBR:

sudo sysctl -w net.ipv4.tcp_congestion_control=bbr

BBR often delivers higher throughput than the default CUBIC algorithm on networks with even small amounts of packet loss. Check what is available with sysctl net.ipv4.tcp_available_congestion_control.

Common iperf3 Error Messages and Fixes

“Connection refused”: The server is not running, or a firewall is blocking port 5201. Start iperf3 -s on the server, and open the port with sudo ufw allow 5201 if you use UFW, or with sudo firewall-cmd --add-port=5201/tcp --permanent on firewalld.

“iperf3: error – unable to read from stream”: A firewall on the server is intercepting TCP control packets. Check sudo iptables -L -n and look for REJECT or DROP rules on port 5201.

“read failed: Connection reset by peer”: The server process crashed mid-test, or the kernel killed it. Check dmesg for OOM messages on the server.

“iperf3: warning – path MTU may not be optimal”: The MTU along the path is smaller than 1500. Check switch MTU settings and consider jumbo frames if both endpoints support it.

Speed capped at exactly 100 Mbps on a gigabit link: Your cable is bad, the switch port is bad, or the NIC negotiated down. Replace the cable first. If the problem persists, try a different switch port.

High CPU usage on one machine during the test: Software-only checksum offload is doing the work in the CPU. Disable it as a test:

sudo ethtool -K eth0 rx off tx off tso off gso off

If the speed jumps, your driver offload settings need adjustment or your NIC hardware is failing.

Frequently Asked Questions

How to test network speed between two computers in Linux?

Install iperf3 on both machines with your package manager. On one machine, run iperf3 -s to start the server. On the other machine, run iperf3 -c SERVER_IP to start the client test. The result prints at the end as the average bandwidth in Mbits/sec.

How to check ethernet speed in Linux?

Run sudo ethtool eth0 and look at the Speed line. You can also run ip link show eth0 to see the negotiated speed from the kernel’s perspective. A healthy gigabit link reports 1000Mb/s with Full duplex.

What is a good iPerf3 bandwidth score?

For a wired 1 Gbps link, anything above 800 Mbits/sec is healthy. For 10GbE, expect 7 to 9.4 Gbits/sec. For WiFi 6 at close range, 500 to 700 Mbits/sec is realistic. Numbers consistently 30 percent below the link rate indicate a real bottleneck worth investigating.

How to test LAN speed?

Run iperf3 in server mode on one machine with iperf3 -s, then run iperf3 -c SERVER_IP from the other. For more thorough testing, use -P 4 to test parallel streams, -R for reverse direction, -t 60 for a 60-second test, and -u -b 1G for UDP packet loss and jitter measurement.

Conclusion

Diagnosing slow LAN transfer speeds between Linux machines with iperf3 comes down to a four-step workflow: verify the link speed with ethtool, start the server, run client tests in both directions, and compare the result against disk and CPU measurements. When iperf3 disagrees with your real file transfers, the bottleneck is almost always disk, protocol, or CPU, not the network itself.

Run the diagnostic steps above on your own setup the next time a transfer feels slow. You will find the cause faster than guessing, and the numbers you collect will help you decide whether the fix is a new cable, a protocol change, a disk upgrade, or a sysctl tweak.

Leave a Comment