Some of you may know that I host this website on a Raspberry Pi 5. I use Raspberry Pi OS Lite, which is a minimal Debian-based operating system that is lean and minimal without excluding anything that would break any features of the Pi itself. I’ve got the 4 GB model, and I don’t think I’ve ever used more than 400-500 MB of RAM during normal server operation. So why slim it down even more? Well, more software equals a larger attack surface, more potential software bugs, and so on.
In a situation where I’m never using the built-in WiFi and Bluetooth radios, there’s no benefit in having their drivers loaded into the kernel. Having unused code running can only increase the likelihood of exploitation, unexpected behavior, bugs, or other unwanted results. These devices also consume power, albeit a small amount, and probably even less when they aren’t connected to a network or device.
Now, I’ve found the drivers on the Raspberry Pi to be pretty good. Honestly, I’ve never had an issue. But since I’m literally not using any wireless on this thing—it’s connected to my network switch with less than a foot of Cat6 Ethernet cable—why bother? If nothing else, you’ll free up a few megabytes of memory. Perhaps an even more tangible benefit is having fewer items cluttering your systemd services and process lists when you check with top or htop.
After removing the following, I saw my memory usage drop to just 125 MB initially. That’s 125 MB of memory used while running Debian 12, with my Apache2 HTTP/HTTPS server and Pi-hole DNS. That’s not bad—kind of impressive, actually!
- Stopped & Disabled:
- Audio (via config.txt)
- avahi-daemon
- bluetooth
- ModemManager
- NetworkManager
- triggerhappy
- wpa_supplicant
Most of these are self-explanatory. As for the less obvious names, avahi is sort of like Apple’s Bonjour service; it’s for mDNS/local device discovery. I knew I didn’t need it, but if you’re not sure, leave it alone. Triggerhappy is a hotkey daemon, which is an easy one to disable on my totally headless system. Audio can be disabled by commenting a line in /boot/firmware/config.txt:
dtparam=audio=off`
And since I was in there anyways, I also commented a couple other lines:
camera_auto_detect=1
display_auto_detect=1
ModemManager, Bluetooth, and wpa_supplicant can just be turned off if you don’t plan on using WiFi or Bluetooth.
sudo systemctl stop ModemManager
sudo systemctl disable ModemManager
Repeat the same two commands for the other daemons.
Now, I’m not making this a full tutorial, and there are two reasons for that. For starters, I’m feeling kind of lazy, and I don’t want to have to redo everything to make sure my directions are 100% correct.
If you want to get rid of NetworkManager too, you’ll want to set up networking manually first. In my case, I edited /etc/network/interfaces and added the following:
auto eth0
iface eth0 inet static
address 10.16.17.10/23
gateway 10.16.16.1
dns-search lan
dns-nameservers 10.16.16.1
If you’re not sure, just leave NetworkManager installed. In my case, I went with a static configuration because I didn’t want to have a daemon running for the DHCP client. If your subnet mask is 255.255.255.0, you would use /24.
But the other very real reason is: If you’re not confident yet in how to disable these things, you probably shouldn’t. Do a bit more research first anyways.
When making changes to your system, have an up-to-date backup because you never know when a change could leave you with a non-booting system. Also, when changing the networking system, it should go without saying that doing so can leave you locked out of a headless system. So only proceed if you have a means of getting back in to fix it should you mess up.
This is really more of a journal of my experience setting this up, for those with some experience to get ideas from. It isn’t meant as a tutorial by any means. I just wanted to share how I got my idle RAM usage down to 3%, with my services running.