Booting, init systems and services
Firmware and bootloaders, how the kernel starts the first process, systemd units versus init scripts, targets and dependencies, and where to find service logs.
The boot sequence
- Firmware (UEFI or BIOS) initialises hardware and finds a bootable device or loader.
- The bootloader loads the kernel and an initial ramdisk into memory and hands over control.
- The kernel initialises devices, mounts the root file system and starts the first process, PID 1.
- PID 1 brings up services according to its configuration and reaches the default target.
- Login prompts, display managers and user services start.
- On shutdown, PID 1 stops services in reverse dependency order.
systemd-analyze # total boot time and the biggest stages
systemd-analyze blame | head -15 # slowest units
systemd-analyze critical-chain # the path that determined the boot time
journalctl -b # this boot's log
journalctl -b -1 # previous boot, useful after a failed one
journalctl -b --list-boots # available bootssystemd units and where they differ from init scripts
# /etc/systemd/system/api.service
[Unit]
Description=API server
After=network-online.target
Wants=network-online.target
[Service]
Type=exec
User=app
WorkingDirectory=/srv/api
ExecStart=/srv/api/bin/server --config /etc/api.toml
Restart=on-failure
RestartSec=2
LimitNOFILE=65536
Environment=LOG_LEVEL=info
# apply resource limits rather than a shell wrapper
MemoryMax=512M
CPUQuota=150%
[Install]
WantedBy=multi-user.target| Aspect | init scripts | systemd |
|---|---|---|
| Dependencies | Order by a numeric prefix | Declared with After and Requires |
| Parallel start | Rarely | Yes, by default |
| Restart on failure | Shell logic you write | Restart=on-failure |
| Resource limits | Wrapped in ulimit calls | Directives in the unit |
| Logging | Redirect to a file yourself | Captured in the journal |
| Socket activation | Not available | Supported per socket unit |
| Enable on boot | Symlink by convention | systemctl enable |
systemctl daemon-reload # after editing a unit file
systemctl enable --now api.service
systemctl status api.service
systemctl restart api.service
systemctl list-dependencies api.service
journalctl -u api.service -f # follow one service
journalctl -u api.service --since "1 hour ago" -p errTargets and troubleshooting a boot
- A target is a group of units;
multi-user.targetreplaces run level 3 andgraphical.targetreplaces run level 5. systemctl set-default multi-user.targetchanges the default boot target.systemctl rescueandsystemctl emergencybring up a minimal environment for repair.- A failing unit does not necessarily stop the boot; check
systemctl --failedrather than assuming success. - Boot parameters can disable a service or drop to a shell:
systemd.unit=rescue.target,singleorrd.break.
systemctl --failed
systemctl list-units --state=failed
systemctl cat api.service # the effective unit plus drop-ins
systemctl show api.service -p Environment -p Restart
# a temporary override rather than editing the packaged unit
# systemctl edit api.service💡
Use
systemctl edit to add a drop-in override instead of modifying a unit that the package manager owns. Upgrades will overwrite your changes to the original file, and the failure appears weeks later during an unrelated update.FAQ
Why does my service work when started by hand but fail at boot?
Almost always a missing dependency or environment. The interactive shell provides a PATH, a working directory and a network that are not present at boot; declare them in the unit.
How do I see why a service failed to start?
systemctl status shows the last lines, and journalctl -u name -b shows the full output from this boot including the exit code.Related
What an operating system does Containers, namespaces and cgroups
Last refreshed 2026-09-18.