systemd-analyze
systemd-analyze blame
systemd-analyze critical-chainThese show kernel vs userspace time and the slowest units. (wiki.archlinux.org)
-
Boot from NVMe (Pi 5) and put it first in the boot order:
sudo -E rpi-eeprom-config --edit # e.g. try NVMe first, then SD: BOOT_ORDER=0xf416(Right-to-left order; f=retry). (jeffgeerling.com)
-
Keep only the devices you’ll ever boot from in BOOT_ORDER (don’t include USB/network if unused) to avoid probe timeouts. (Volumio Community)
-
Read-only root (overlayfs) via
raspi-config(“Performance → Overlay FS”). This avoids fsck and journaling delays.- On Bookworm,
raspi-configsetsoverlayroot=tmpfs; if external drives turn read-only, change tooverlayroot=tmpfs:recurse=0(or tune/etc/overlayroot.conf). (Raspberry Pi Stack Exchange)
- On Bookworm,
-
If you can’t go RO, at least add
fsck.mode=skipto/boot/firmware/cmdline.txt(or/boot/cmdline.txtpre-Bookworm) to skip filesystem checks on clean boots. (Ask Ubuntu) -
Mount
noatimeon your RW partitions to cut write work during boot. (General Linux best-practice.)
Bookworm moved the boot partition to
/boot/firmware—that’s whereconfig.txt/cmdline.txtlive now. (Raspberry Pi)
-
Headless? Disable radios and audio in
/boot/firmware/config.txt:dtoverlay=disable-wifi dtoverlay=disable-bt dtparam=audio=off(Saves driver init time.) (Raspberry Pi Stack Exchange)
-
Don’t block on networking at boot:
-
Mask whatever “wait-online” you have (varies by image):
sudo systemctl mask systemd-networkd-wait-online.service || true sudo systemctl mask NetworkManager-wait-online.service || true
Or configure wait-online to
--any/ specific interface only. (wiki.archlinux.org) -
If you use
dhcpcd, run it in background (doesn’t hold boot) or use a static IP. (bbs.archlinux.org)
-
-
Boot to console, not desktop (unless you need a GUI):
sudo systemctl set-default multi-user.target
Then only start your app. (You can still launch a compositor later.)
Disable services you don’t need (examples—pick from your systemd-analyze blame output):
sudo systemctl disable --now bluetooth.service hciuart.service avahi-daemon.service triggerhappy.serviceRe-run systemd-analyze blame and repeat until only essentials remain. (Red Hat Documentation)
- Remove serial console from
/boot/firmware/cmdline.txtif you don’t use it (dropconsole=serial0,115200so the kernel isn’t spewing to UART). - Autologin straight to your app (TTY): make
getty@tty1autologin andexecyour binary; or even useinit=/usr/bin/your-appto make your process PID 1 for ultra-fast boots (advanced; you must mount /proc,/sys,/dev yourself). (docs.kernel.org) - Custom/minimal OS (Buildroot/BusyBox + only built-in drivers + LZ4 kernel): this is how folks get ~2–3s to app on older Pis; <5s is easy. (bootlin.com)
- NVMe first in
BOOT_ORDERand update EEPROM. (jeffgeerling.com) - Enable overlay FS (or add
fsck.mode=skip). (Raspberry Pi Stack Exchange) systemctl set-default multi-user.targetand mask wait-online. (wiki.archlinux.org)- Disable Wi-Fi/BT/audio overlays and unneeded services. (Raspberry Pi Stack Exchange)
- Autostart your app on TTY1; keep network coming up in the background.
That combo typically lands around 1–2s kernel + 2–3s userspace on Pi 5 with NVMe—i.e. ~3–5s to your app. Community reports show even ~4.0–4.5s to a full desktop with aggressive trimming. (forums.raspberrypi.com)