Skip to content
DevOps devops linux-admin 5 min read

The Boot Process & Targets

When you press the power button on an Ubuntu server, a precise chain of events runs before you ever see a login prompt. Understanding this chain — firmware, then a bootloader, then the kernel, then systemd — helps you fix servers that won’t start, choose whether a machine boots to a desktop or a plain terminal, and reason about why services come up in a certain order. This page walks through each stage in plain English and shows you the exact commands to inspect and control it on Ubuntu 22.04 and 24.04 LTS.

The boot sequence, stage by stage

Booting is a hand-off race: each stage starts the next, then steps out of the way. Here is the full chain on a modern Ubuntu server.

  1. Firmware (UEFI or BIOS) — The first code that runs, stored on a chip on the motherboard. UEFI (Unified Extensible Firmware Interface) is the modern standard; BIOS (Basic Input/Output System) is the old one. The firmware runs a quick hardware check (POST, the Power-On Self-Test), then looks for a bootloader on disk and runs it.
  2. GRUB (the bootloader) — GRUB (GRand Unified Bootloader) is a small program whose only job is to load an operating system. It shows the boot menu, then loads the Linux kernel (the core of the operating system that talks to hardware) into memory and starts it.
  3. The kernel — The kernel initializes hardware (CPU, memory, disks, network cards), mounts the root filesystem, and then starts the very first user-space program, called init. On Ubuntu, that init program is systemd.
  4. systemd (PID 1) — systemd is the system and service manager. It always runs as process ID 1 (PID 1). It starts everything else — networking, logging, your web server, your database — in the right order, then brings the system to its default target (more on targets below).
# See how long each stage took on the last boot
systemd-analyze

Output:

Startup finished in 4.512s (firmware) + 2.103s (loader) + 1.884s (kernel) + 6.220s (userspace) = 14.720s
graphical.target reached after 6.210s in userspace.

Tip: To find what is slowing your boot, run systemd-analyze blame. It lists every service ranked by how long it took to start, so you can spot the slow one.

GRUB: choosing what boots

GRUB is where you pick a kernel (Ubuntu keeps the old one as a fallback) or enter recovery mode (a minimal boot used for repairs). On a server you usually let it boot automatically, but you control its behavior through a config file.

You never edit GRUB’s generated config directly. Instead you edit /etc/default/grub and regenerate.

sudo nano /etc/default/grub
# /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
  • GRUB_TIMEOUT — how many seconds the menu waits before booting the default entry.
  • GRUB_DEFAULT — which menu entry boots by default (0 is the first).

After any change, regenerate the real config so GRUB picks it up.

sudo update-grub

Output:

Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-31-generic
Found initrd image: /boot/initrd.img-6.8.0-31-generic
done

systemd targets replace runlevels

Older Linux systems used runlevels — numbered states (0–6) that defined what the machine was doing (halted, single-user, multi-user, etc.). systemd replaced runlevels with targets: named groups of services that represent a system state. Targets are more flexible because a target can depend on other targets and services by name instead of by number.

The two you care about most on a server:

TargetOld runlevelWhat it meansWhen to use it
multi-user.target3Full system, networking on, no graphical desktop — just text consoles and SSHThe normal choice for servers — no wasted memory on a GUI
graphical.target5Everything in multi-user plus a graphical login screen and desktopDesktops and workstations, or a server you manage with a GUI
rescue.target1 (single-user)Minimal system, root shell, most services stoppedRepairing a broken system
emergency.targetBare minimum, root filesystem mounted read-onlyLast-resort recovery when even rescue fails
reboot.target6Restarts the machineTriggered by reboot
poweroff.target0Shuts the machine downTriggered by poweroff

Getting and setting the default target

The default target is the state systemd brings the machine to at the end of boot. On a fresh Ubuntu Server install it is multi-user.target; on Ubuntu Desktop it is graphical.target.

Check the current default.

systemctl get-default

Output:

graphical.target

To save memory on a server, switch the default to text-only multi-user.target. This survives reboots.

sudo systemctl set-default multi-user.target

Output:

Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /usr/lib/systemd/system/multi-user.target.

Gotcha: set-default only changes what happens on the next boot. To switch the running system right now without rebooting, use isolate (below).

You can also change the active target immediately. isolate starts the named target and stops anything not part of it.

# Switch the live system to text-only mode right now
sudo systemctl isolate multi-user.target

To inspect what is going on, list targets and view the boot default.

# Show all loaded targets and whether they are active
systemctl list-units --type=target

Output:

UNIT                   LOAD   ACTIVE SUB    DESCRIPTION
basic.target           loaded active active Basic System
cryptsetup.target      loaded active active Local Encrypted Volumes
getty.target           loaded active active Login Prompts
multi-user.target      loaded active active Multi-User System
network-online.target  loaded active active Network is Online
sysinit.target         loaded active active System Initialization

To boot into a different target just once (for troubleshooting), add its name at the GRUB menu: press e on the boot entry, append systemd.unit=rescue.target to the linux line, then press Ctrl+X to boot. The change is temporary and does not touch your config.

Best Practices

  • Run servers in multi-user.target — a GUI wastes RAM and CPU and widens the attack surface for no benefit on a headless machine.
  • Always edit /etc/default/grub and then run sudo update-grub; never hand-edit /boot/grub/grub.cfg, because it is overwritten on the next kernel update.
  • Use systemd-analyze blame after install to catch services that slow your boot, and disable ones you do not need with sudo systemctl disable <service>.
  • Keep GRUB_TIMEOUT at a few seconds on physical servers so you can reach recovery mode, but consider a shorter value on cloud VMs that you never see a console for.
  • Test a new default target with systemctl isolate before committing to it with set-default, so you can confirm the system behaves before a reboot locks it in.
  • Know your escape hatch: appending systemd.unit=rescue.target at the GRUB menu gets you a root shell when a bad config blocks a normal boot.
Last updated June 15, 2026
Was this helpful?