Hello, this is Agata.
In this article, we will be looking at how to measure network performance between Linux, Mac and Windows terminals.
However, if you are using Windows, please go to Microsoft’s page.
It seems that people are measuring using iperf3 on Windows without worrying about it, but as this Microsoft article explains, because it is not running on Windows’ native API, there is a possibility that the results will differ from the actual performance.
Windows users should refer to the above Microsoft article and use ntttcp.
Of course, iperf3 is not compatible with Windows to Linux or Windows to Mac.
For Linux, the Linux version of ntttcp has been released, so use this.
Unfortunately, the Mac version of ntttcp does not appear to have been released. If you want to measure between Mac and Windows, you may have to use iperf, although it is not accurate.
So, let’s get back on track and look at measuring on Linux or Mac.
To measure, you need to install iperf3 on both of the two devices you want to measure.
There is a server side and a client side of iperf3, but you can switch between them using options, so you can install the same version on both.
First, let’s install ipef3.
we will use Ubuntu as an example.
sudo apt install iperf3
brew install iperf3
The process is basically the same for both Linux and Mac.
One of the two devices is designated as the server, and the other as the client. You can decide which one is which as you like.
Start iperf3 in server mode on the device that will be the server, and start iperf3 in client mode on the device that will be the client.
If your firewall is enabled, disable it or open the port used by iperf3 (the default is 5201).
Use the following command to start the server side first.
iperf3 -s
The following execution results will be displayed on the client side.
Connecting to host 192.168.0.1, port 5201
[ 5] local 192.168.0.129 port 50893 connected to 192.168.0.1 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 75.9 MBytes 636 Mbits/sec
[ 5] 1.00-2.00 sec 61.0 MBytes 511 Mbits/sec
[ 5] 2.00-3.00 sec 68.8 MBytes 578 Mbits/sec
[ 5] 3.00-4.00 sec 71.2 MBytes 598 Mbits/sec
[ 5] 4.00-5.00 sec 67.0 MBytes 560 Mbits/sec
[ 5] 5.00-6.00 sec 70.0 MBytes 589 Mbits/sec
[ 5] 6.00-7.00 sec 72.9 MBytes 610 Mbits/sec
[ 5] 7.00-8.00 sec 60.0 MBytes 503 Mbits/sec
[ 5] 8.00-9.00 sec 72.8 MBytes 610 Mbits/sec
[ 5] 9.00-10.00 sec 63.9 MBytes 538 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.00 sec 683 MBytes 573 Mbits/sec sender
[ 5] 0.00-10.02 sec 682 MBytes 571 Mbits/sec receiver
iperf Done.
If you start it as it is, the measurement time is set to 10 seconds. This may cause measurement errors to increase due to temporary fluctuations in network load.
Therefore, it may be better to set the measurement time to a longer time, such as 60 seconds.
The measurement time can be set using the -t option.
iperf3 -c 192.168.8.3 -t 60
Incidentally, when you start the client normally, the data is sent from the client to the server and measured.
If you want to measure the speed in the opposite direction for some reason, you can switch it by simply adding -R to the client side options.
iperf3 -c 192.168.0.1 -R
Connecting to host 192.168.0.1, port 5201
Reverse mode, remote host 192.168.0.1 is sending
[ 5] local 192.168.0.129 port 51116 connected to 192.168.0.1 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 76.8 MBytes 641 Mbits/sec
[ 5] 1.00-2.00 sec 79.2 MBytes 667 Mbits/sec
[ 5] 2.00-3.00 sec 81.0 MBytes 677 Mbits/sec
[ 5] 3.00-4.00 sec 80.6 MBytes 676 Mbits/sec
[ 5] 4.00-5.00 sec 80.4 MBytes 674 Mbits/sec
[ 5] 5.00-6.00 sec 80.4 MBytes 674 Mbits/sec
[ 5] 6.00-7.00 sec 78.9 MBytes 662 Mbits/sec
[ 5] 7.00-8.00 sec 76.5 MBytes 644 Mbits/sec
[ 5] 8.00-9.00 sec 80.2 MBytes 671 Mbits/sec
[ 5] 9.00-10.00 sec 78.1 MBytes 657 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.02 sec 795 MBytes 666 Mbits/sec 12 sender
[ 5] 0.00-10.00 sec 792 MBytes 664 Mbits/sec receiver
iperf Done.
If you are planning to process the data in some way later, it may be more convenient to output it in JSON format.
As you can see from the following sample, it is output in more detail.
iperf3 -c 192.168.0.1 -J
{
"start": {
"connected": [{
"socket": 5,
"local_host": "192.168.0.129",
"local_port": 51240,
"remote_host": "192.168.0.1",
"remote_port": 5201
}],
"version": "iperf 3.18",
"system_info": "Darwin Agata-MacBook-Pro.local 23.6.0 Darwin Kernel Version 23.6.0: Thu Sep 12 23:34:49 PDT 2024; root:xnu-10063.141.1.701.1~1/RELEASE_X86_64 x86_64",
"timestamp": {
"time": "Fri, 31 Jan 2025 05:12:25 UTC",
"timesecs": 1738300345
},
"connecting_to": {
"host": "192.168.0.1",
"port": 5201
},
"cookie": "2lmxmjdwqnodwixbylwsplixxex4geldlzo6",
"tcp_mss_default": 1448,
"target_bitrate": 0,
"fq_rate": 0,
"sock_bufsize": 0,
"sndbuf_actual": 131072,
"rcvbuf_actual": 131072,
"test_start": {
"protocol": "TCP",
"num_streams": 1,
"blksize": 131072,
"omit": 0,
"duration": 60,
"bytes": 0,
"blocks": 0,
"reverse": 0,
"tos": 0,
"target_bitrate": 0,
"bidir": 0,
"fqrate": 0,
"interval": 1
}
},
"intervals": [{
"streams": [{
"socket": 5,
"start": 0,
"end": 1.004466,
"seconds": 1.0044660568237305,
"bytes": 72351744,
"bits_per_second": 576240429.49773228,
"omitted": false,
"sender": true
}],
"sum": {
"start": 0,
"end": 1.004466,
"seconds": 1.0044660568237305,
"bytes": 72351744,
"bits_per_second": 576240429.49773228,
"omitted": false,
"sender": true
}
}, {
"streams": [{
"socket": 5,
"start": 1.004466,
"end": 2.002778,
"seconds": 0.998311996459961,
"bytes": 73007104,
"bits_per_second": 585044388.99971151,
"omitted": false,
"sender": true
}],
"sum": {
"start": 1.004466,
"end": 2.002778,
"seconds": 0.998311996459961,
"bytes": 73007104,
"bits_per_second": 585044388.99971151,
"omitted": false,
"sender": true
}
}, {
"streams": [{
"socket": 5,
.
.
.