iPerf for Performance Testing

Over the years of working with customers and other fellow engineers I have run into a number of situations where wired and wireless performance testing was requested. This has ranged from “look how much bandwidth I can push through this AP” to just level setting expectations and verification. Typically I see people running various internet speed tests to verify performance. This is in my opinion a good way to disappoint yourself and all involved. Internet speed tests are never a guarantee and always rely on not only your internet bandwidth and availability (which can vary depending on usage and load from others), firewall capability, but most importantly – speed test server availability.

Believe it or not, anyone with a gigabit pipe to the internet, static IP, and the ability to map DNS can be a speed test server node. This does count out most homelabbers, but I have witnessed a few organizations that ran speed test nodes that, in my opinion, should never have been qualified. So that leaves me with this: Learn to use tools that can run locally on your network. This allows you to properly test your environment without relying on someone else’s server to verify that you have adequately designed, deployed, and tuned your environment to support the necessary bandwidth requirements for your users.

The two most common scenarios where iPerf fits the bill:

Throughput testing – This format can be used for performance testing mesh links and the unfortunate events where a customer has been sold on marketing “numbers” instead of real world performance.

Client load testing – This is often misconstrued as throughput testing. However, this should be based on number of clients + expected SLA. This is often seen with 30+ clients connecting to an AP and running some sort of performance test.

To get started using iPerf you have to remember that it operates in a client / server configuration. You never want your server to be the bottleneck on the network unless you have no other choice. That being said I highly recommend a device with at least a gigabit adapter which can be small and compact like the ODroidC2 (Thanks WLPC!).

1. Download iperf for your devices.

For Mac and Windows – You can download the application from: https://iperf.fr/iperf-download.php . If you are savvy with Windows 10 you can also install the linux subsystem for windows and then “apt-get install iperf3“. With Mac you could also use homebrew and install via “brew install iperf3“.

For linux – Just use your friendly package manager: yum/apt/pacman and install your iperf3 package.

For Android – There are many apps available via the Play Store as well as Access Agility’s WiFiPerf endpoint app: (https://www.accessagility.com/wifiperf)

For iOS – There are a few apps available via the app store or once again using WiFiPerf from Access Agility: (https://www.accessagility.com/wifiperf)

2. Choose which side you would like to have run as the server and the client.

I highly recommend running the remote devices as servers. This way you can easily initiate multiple iperf sessions without having to get up and touch each device. The key is to utilize the option -R so that the process is run in reverse as if the wired machine is the server.

Screen Shot 2017-04-19 at 11.05.55

3. Choose the options that you may want to implement to tailor the test to your scenario. Here are some common ones I use:

-w {TCP Window in KB or MB} #### This sets the amount of data that can be sent before there needs to be an acknowledgement. This can be tricky as loss will affect throughput as the packets need to be retransmitted. That being said, fewer ACKs can mean more throughput as there is less time spent sending and receiving acknowledgements on the network. It is always good to run a few tests to get a median number. I usually stick with 1M – 2M.

-P {number of concurrent client streams} #### This creates multiple streams. I usually do anywhere from 5-10 when I do want to run multiple streams. This will allow iperf to spread the streams across multiple processors and could be handy if you are on a low clock CPU with multiple cores. YMMV

-S {IP type of service value} #### Check this handy page out for the values to use: https://www.tucny.com/Home/dscp-tos. This is an option for changing the traffic markings to, for example: Expedited Forwarding with “0xB8”. I’ve used this for testing DSCP marking preservation quite often.

-t {time in seconds to run the test} #### This is great to set for a longer period of time when you are trying to initiate multiple concurrent tests. I usually run for 120-180 seconds when I am running with multiple devices.

-u #### runs as UDP. This can allow you to stress test a link to find out what speed you are able to attain without loss as well as displays jitter and packet loss. Highly recommend pairing with the next option.

-b {kbps or mbps} #### sets the kbps or mbps of the transmission. If running with -P for multiple streams it will cap each stream at the set value. example: “-b 10M“. This is a great use for SLA testing where you are expecting to provide X number of clients with a certain amount of bandwidth.

-i {time in seconds} #### update interval on screen; default is 1 second. Can be useful when running large numbers of concurrent tests to increase the interval, or disable with “-i 0”

–logfile {filename} #### outputs what would normally be in your terminal to a log file of your choosing.

4. Run your tests and review the output. 

The one fun thing about iPerf is that you get to do a bit of trial and error testing typically to find what settings work for the configurations you’ve implemented. It can be helpful to have a few examples which I will include below. As one of my friends said recently, “step 1. copy/paste code. step 2. troubleshoot error message. step 3. read initial post where code was copied from.” That being said don’t be afraid to look at the iPerf3 manpage at: https://www.mankier.com/1/iperf3 to really get a deep dive and create your own tests.

Examples of Client configurations:

Throughput testing:

“iperf 3 -c {server ip} -w 1M -P 5 -t 60 -i 5” #### 1M TCP windows, 5 parallel streams, for 60 seconds with 5 second update intervals.

“iperf 3 -c {server ip} -w 1M -P 5 -t 60 -i 5 -S 0x08” #### the same as above with traffic marked as Background CS1 / DSCP 8.

“iperf 3 -c {server ip} -u -t 60 -i 5 -b {expected throughput of link}” #### The nice thing here is you will be able to see if there was loss or jitter on the link.

For example if you were testing throughput on an expected 500mbps line to a server at your command could be:

iperf3 -c -u -t 30 -b 500M

and the neat output:

– – – – – – – – – – – – – – – – – – – – – – – – –

[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams

[  4]   0.00-30.00  sec  1.74 GBytes   499 Mbits/sec  0.015 ms  2/1292334 (0.00015%) 

[  4] Sent 1292334 datagrams

SLA Testing with a client connecting to multiple servers:

“iperf3 -c {server ip} -u -b 10M -t 60 -i 5 -R” #### this is a fairly basic udp test attempting at 10mbps for 60 seconds with updates every 5 seconds.

“iperf3 -c {server ip} -u -b 10M -t 60 -i 60 -R –logfile test1.txt” #### runs iPerf with UDP at an attempted 10Mbps for 60 seconds in reverse. The -i matched with the command runtime and logfile command will only output the results to a text file called test1.txt

The above tests can also be run as TCP with the -b option. The one nice thing about running as UDP is you can see how much loss occurred in transmission.


Good Luck!! And as always please leave a comment below if you find any mistakes or have anything to add!