I made a few tests to find out how to boost network transfer speed on Raspberry Pi 4 and is it worth the hassle.
Table of Contents
TL;DR
Prefer wired connections when it’s not too inconvenient. For maximum data throughput, you should also use an SSD because regular SD cards won’t let you fully utilize the potential of your wired connection.
Preface
Raspberry Pi 4 is a capable SBC which comes with two built-in network interfaces: Gigabit Ethernet and IEEE 802.11ac Wi-Fi. Having options is good, but it’s also a common source of confusion. Which interface should we use and why?
In this article, I compare wired and Wi-Fi interfaces in terms of their maximum data throughput. If you’re new to networking, you might also benefit from reading about network latency and its role in the performance of networked software. In short, wired connections usually have an order of magnitude better latency than the wireless ones and that might be more important than the amount of megabytes you can push per second. That said, let’s do some tests!
First, it’s good to keep in mind that we can’t trust the benchmarks completely. Real-world performance can depend on many factors, and it’s always a good idea to reproduce the same tests with your own hardware and in your own environment.
Test Structure
Here is what my test does:
- Generate 1 GB of random data on my laptop
- Send this data to my Raspberry Pi and measure the average speed
- Fetch this data from my Raspberry Pi and measure the average speed
I repeated this test with four different configurations:
- Raspberry Pi that uses Wi-Fi and stores data on SD card
- Raspberry Pi that uses Wi-Fi and stores data on SSD drive
- Raspberry Pi that uses Ethernet and stores data on SD card
- Raspberry Pi that uses Ethernet and stores data on SSD drive
That’s it. Now, it’s time to generate that random data.
Generating Test Data
We can use dd
to generate a new file and /dev/urandom
is a great data source:
dd if=/dev/urandom of=big.file bs=64M count=16 iflag=fullblock
Let’s clarify these arguments and their purpose:
if
- input file. In our case, we attach our input to the stream of random data which is available on any Linux distribution.of
- output file. It’s a name of the file we want to create. Feel free to use any name you want.bs
- in our case, it means that we want to generate our random file piece by piece and there should becount
pieces in it. It also means that we can tweak both arguments, the only important thing is thatbs
*count
should be close to our target size (1 GB).count
- as mentioned above, it’s just a multiplier forbs
Testing Data Throughput Over Wi-Fi and Ethernet
Let’s send some data to Raspberry Pi (Laptop --> Pi
):
rsync --progress big.file pi@cloud.local:~/big.file
big.file
1,073,741,824 100% 32.10MB/s 0:00:31 (xfr#1, to-chk=0/1)
I used rsync
because it’s easy to use, and it reflects my real workloads (syncing a lot of files, doing backups and so on).
Now we can download that big file from the Raspberry Pi and measure the average transfer speed (Laptop <-- Pi
):
rsync --progress pi@cloud.local:~/big.file big.file.back
big.file
1,073,741,824 100% 42.69MB/s 0:00:23 (xfr#1, to-chk=0/1)
That’s it. I repeated this test for each of tested setups and here are the results:
Results
From | To | Interface | Storage | Speed (Mbit/s) | Speed (MB/s) |
---|---|---|---|---|---|
Dell XPS 13 (2018) | Raspberry Pi 4 | Wi-Fi | SD | 58.24 | 7.28 |
Dell XPS 13 (2018) | Raspberry Pi 4 | Wi-Fi | SSD | 55.84 | 6.98 |
Dell XPS 13 (2018) | Raspberry Pi 4 | Gigabit Ethernet | SD | 159.60 | 19.95 |
Dell XPS 13 (2018) | Raspberry Pi 4 | Gigabit Ethernet | SSD | 340.56 | 42.57 |
Raspberry Pi 4 | Dell XPS 13 (2018) | Wi-Fi | SD | 80.72 | 10.09 |
Raspberry Pi 4 | Dell XPS 13 (2018) | Wi-Fi | SSD | 82.00 | 10.25 |
Raspberry Pi 4 | Dell XPS 13 (2018) | Gigabit Ethernet | SD | 339.20 | 42.40 |
Raspberry Pi 4 | Dell XPS 13 (2018) | Gigabit Ethernet | SSD | 341.52 | 42.69 |
Interesting results, but let’s try an alternative approach to measuring network throughput before jumping to any conclusions.
Testing Raspberry Pi 4 Throughput With iPerf
We can easily measure “raw” network performance by moving as much data as possible between two computers for a certain period of time. One of those computers has to play a role of a client by generating a lot of gibberish and sending it to the second machine which can simply discard all of that traffic upon arrival.
There are many ways to perform such a test but iperf
is a kind of industry standard, and it’s very easy to use, which makes it a good choice for our quick test.
Let’s make Raspberry Pi 4 a server:
ssh pi@pi.local
sudo apt install iperf
iperf --server
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
Now, we can use iperf
from another computer and instruct it to connect to a Raspberry Pi in order to measure the network throughput between them:
sudo apt install iperf
iperf --client pi.local
Client connecting to cloud.local, TCP port 5001
TCP window size: 85.0 KByte (default)
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 1.10 GBytes 942 Mbits/sec
Here are my results for wired and Wi-Fi connections:
Interface | Speed (Mbit/s) |
---|---|
Gigabit Ethernet | 942 |
Wi-Fi (IEEE 802.11ac) | 86 |
Seems like both tests point to the same conclusion.
Conclusion
Although using Wi-Fi is more convenient because it gives you more flexibility, don’t expect your network transfer speed to be anywhere above 86 Mbit/s if you connect your Raspberry Pi wirelessly. 86 Mbit/s is actually not that bad if you use an SD card because many modern SD cards can’t go beyond ~80 Mbit/s when they write data, although they can read a bit faster and not being able to use this extra reading speed is the main drawback of using Wi-Fi on a Raspberry Pi 4.
Things get a bit different if you prefer to store your data on an SSD drive. Modern solid state drives can move gigabytes in seconds, but your Wi-Fi connection wouldn’t allow you to use any that extra throughput. Switching to a wired connection boosts transfer speed up to about 30-40 MB/s when using rsync
, which is better, but still a far cry from the theoretical limit of 125 MB/s (that’s the max speed of a Gigabit Ethernet adapter that is used in Raspberry Pi 4). It might be due an encryption overhead which puts some pressure on a CPU, making it a bottleneck. That’s precisely why benchmarking is hard, there are many components that might affect the results.