Previously, I published a Pinebook Pro review article on this blog. Similar to the Pinebook Pro, the Raspberry Pi and, more recently, the Raspberry Pi 4 are also ARM-based.
With good results, I’ve applied some of the optimizations mentioned in that previous article to the Raspberry Pi 4. I wanted to share these tweaks and hopefully find out if you also experience the same improvements to performance.
After adding a Raspberry Pi to my Homelab, at times when memory was low, it became very unresponsive and would even freeze. To help address this, I added ZRAM and made a few changes to kernel parameters.
Enable ZRAM on the Raspberry Pi
ZRAM creates RAM based block storage named /dev/zram0 (or 1, 2, 3, etc). Pages written there are compressed and stored in memory. This allows for very fast I/O and the compression savings provide additional memory.
The Raspberry Pi 4 has a max memory of 1GB, 2GB, 4GB or 8GB of RAM. I will be using the 1GB model. This requires some adjustments depending on your use case.
With 1GB of ZRAM, the default /swapfile (slow!) will be the last resort. I ended up using this zram-swap script to install and auto-configure.
The instructions are listed on that page. Here’s how to install it:
git clone https://github.com/foundObjects/zram-swap.git cd zram-swap && sudo ./install.sh
Optional, if you would like to edit config:
Alternatively, you can enable ZRAM by installing
zram-tools. If you use this method, be sure to edit the config located in
/etc/default/zramswap and setup around 1GB of ZRAM:
sudo apt install zram-tools
Once installed, you can see the stats of ZRAM storage using the following command:
sudo cat /proc/swaps Filename Type Size Used Priority /var/swap file 102396 0 -2 /dev/zram0 partition 1185368 265472 5 pi@raspberrypi:~ $
Add Kernel Parameters to make better use of ZRAM
Now, rather than leaving swapping till the last minute, which often brings the Raspberry Pi to a crippling halt, i’ve added the following lines to /etc/sysctl.conf and rebooted.
These lines will:
- Delay the inevitable, running out of memory. This is done by increasing the kernel’s cache pressure.
- Start preparing for being out of memory sooner by increasing the tendency of your Raspberry Pi to swap. However, swap will now be stored via much faster ZRAM!
Here are the lines you’ll want to add at the end of your /etc/sysctl.conf file:
vm.vfs_cache_pressure=500 vm.swappiness=100 vm.dirty_background_ratio=1 vm.dirty_ratio=50
Then reboot, or enable with:
sudo sysctl --system
vm.vfs_cache_pressure=500 – increases cache pressure, which increases the tendency of the kernel to reclaim memory used for caching directory and inode objects. You will use less memory over a longer period. The performance hit is negated by the downside of swapping sooner.
vm.swappiness=100 – Increasing how aggressively the kernel will swap memory pages since we are using ZRAM first.
vm.dirty_background_ratio=1 & vm.dirty_ratio=50 – background processes will start writing right away when it hits the 1% limit but the system won’t force synchronous I/O until it gets to 50% dirty_ratio.
These four lines (when used with ZRAM) will help; if, like me, you know that you will eventually end up using more than the installed memory = swapping. Thus, knowing that you will swap and that ZRAM makes swapping less expensive and can store the data compressed 3 times smaller and begin this swap exchange sooner rather than later.
The cache pressure helps because we are telling the kernel… “hey, look man, I don’t have any extra memory lying around to use for cache, so please get rid of it asap and only store the most frequently used/important data”.
Even with reduced caching, if over time we use most of the installed memory, the kernel will start opportunistic swapping to ZRAM much sooner so that CPU (compression) and swap I/O aren’t delayed until too late/all at once. ZRAM uses some CPU for compression, but in most low-memory scenarios, this is much less of a performance hit than swapping without ZRAM enabled.
Let’s look again at the results:
pi@raspberrypi:~ $ free -h total used free shared buff/cache available Mem: 926Mi 471Mi 68Mi 168Mi 385Mi 232Mi Swap: 1.2Gi 258Mi 999Mi pi@raspberrypi:~ $ sudo cat /proc/swaps Filename Type Size Used Priority /var/swap file 102396 0 -2 /dev/zram0 partition 1185368 264448 5
264448 in ZRAM is almost 1G of data compressed. Everything swapped to ZRAM and nothing hit the much slower the /swapfile. Give this setup a try; this will work on all Raspberry Pi models. My setup went from unusable and freezing to performant and stable.
In the near future, I hope to follow up and update this article with some before vs. after results. I don’t have the time currently to do this. In the meantime, feel free to perform your tests and let me know in the comments. The Raspberry Pi 4 is a beast with these tweaks. Enjoy!