The boot process & systemd-analyze

From firmware to a running system, timed.

Advanced12 min · lesson 6 of 17

Understanding boot end to end demystifies a whole class of "it will not come up" problems. The sequence: firmware (BIOS/UEFI) hands off to the bootloader (GRUB), which loads the kernel and an initramfs (a tiny temporary root filesystem with the drivers needed to find the real one); the kernel initializes hardware and mounts the real root; then it starts PID 1 (systemd), which brings the system to its default target by starting everything that target wants. Each stage can fail, and knowing them tells you where to look.

From power-on to a running system
1firmware
UEFI/BIOS → bootloader
2GRUB
loads kernel + initramfs
3kernel
drivers, mount real root
4systemd (PID 1)
reach default target
A hang tells you the stage: no GRUB = bootloader/disk; kernel panic = kernel/initramfs; stuck after = a systemd unit.

systemd-analyze: time the boot

systemd records how long each unit took to start, and systemd-analyze turns that into an accountable number. systemd-analyze time gives the total (firmware, loader, kernel, userspace); blame ranks units by how long they took; and critical-chain shows the dependency path that actually determined boot time — which is the one to optimize, since parallel units do not add up. This turns "boot feels slow" into "this specific unit added nine seconds."

terminal
$ systemd-analyze time
Startup finished in 3.1s (firmware) + 2.2s (loader) + 4.8s (kernel) + 21.3s (userspace)
$ systemd-analyze blame | head -3 # slowest units
11.402s cloud-init.service
6.210s NetworkManager-wait-online.service
$ systemd-analyze critical-chain # the path that actually gated boot

When boot fails

When a system will not boot fully, the recovery tools follow the stages. From the GRUB menu you can edit the kernel line to add systemd.unit=rescue.target (single-user) or emergency mode, or an older kernel. Once in, journalctl -b (this boot) and journalctl -b -1 (the previous boot, to see what failed before a reboot) show what happened, and systemctl --failed lists units that did not start. Knowing that a failed mount, a hung network-wait, or a bad unit each fail at a predictable point is what makes boot troubleshooting systematic rather than panicked.

A single bad unit can hang the whole boot
A service with a long or infinite start timeout, or a filesystem in /etc/fstab that cannot be mounted, can stall boot for minutes or hang it entirely — systemd waits on dependencies. The fixes: give network waits and custom services sane TimeoutStartSec values, mark non-critical fstab entries nofail so a missing disk does not block boot, and know how to reach rescue.target from GRUB to get in and read journalctl -b when it does hang. One misconfigured unit should never mean an unbootable host, and these settings ensure it does not.