Targets — systemd's Answer to Runlevels

systemd in Depth

Chapter 5 · Targets — systemd's Answer to Runlevels

systemd1-4 defined a target as a synchronization point without going further. This chapter goes further — and resolves grub1-4's own unexplained systemd.unit=rescue.target kernel parameter along the way.

What a Target Actually Is, Formally

systemd1-4 established that a target doesn't "do" anything itself. Formally: a target unit is a named grouping of other units — often implemented as essentially an empty unit that other units Want=/Require=/order themselves relative to. "Reaching a target" means every unit that target itself requires or wants, directly or transitively, has actually been started.

The Common Targets, Mapped to Legacy Runlevels

systemd targetLegacy runlevelMeaning
poweroff.target0Shut down
rescue.target1Single-user/minimal recovery mode
multi-user.target3Full multi-user, no GUI
graphical.target5Multi-user + display manager/GUI
reboot.target6Reboot

graphical.target itself Wants=multi-user.target, since graphical mode is a strict superset — everything multi-user mode provides, plus a display manager on top.

The Default Target

systemctl get-default systemctl set-default multi-user.target

Which target boots by default is determined by a symlink — /etc/systemd/system/default.target pointing at the chosen target — genuinely similar in spirit to systemd1-3's own WantedBy= symlink mechanism, just applied to the top-level boot target rather than an individual service. A headless server typically defaults to multi-user.target; a desktop distro typically defaults to graphical.target.

systemctl isolate — Switching Targets Live

systemctl isolate multi-user.target

Run on a live graphical system, this stops everything not required by multi-user.target — the display manager included — and starts anything multi-user.target requires that wasn't already running. A genuine live runlevel-style switch, no reboot required. A real, practical use: temporarily dropping out of a graphical environment to troubleshoot a display/GPU driver issue, then isolating back to graphical.target once fixed.

Direct Legacy Comparison

systemd1-1's own System V material named telinit 3 as the legacy way to switch runlevels live. That maps directly to systemctl isolate multi-user.target — the same real-world action, but a genuinely different, more expressive mechanism underneath: an actual dependency-resolution operation, not a legacy numbered switch with no explicit relationship to what it starts or stops.

Resolving grub1-4's Own rescue.target

grub1-4 taught appending systemd.unit=rescue.target at the GRUB menu to reach a recovery shell, without explaining what that parameter actually meant. Now it's clear: this tells systemd to boot straight to this target instead of the normal default, bypassing graphical.target/multi-user.target's own much larger set of Wants=/Requires= dependencies entirely, landing in a genuinely minimal environment with far fewer units started — exactly why it's usable for recovery even when something elsewhere in the normal boot chain is broken.

See every active target right now
systemctl list-units --type=target lists every target currently active on the system — a concrete way to see this chapter's own material reflected in real, live system state rather than only reasoning about it abstractly.
systemctl isolate is a real, immediately disruptive action
Isolating to rescue.target on a live production system stops nearly everything non-essential immediately — network services included, in many configurations. Genuinely disruptive to anyone actively using the system; not something to run casually just to "see what happens."

Hands-On Exercises

Exercise 1

Write the command that sets a headless server's default boot target to multi-user.target, and explain why a headless server should never default to graphical.target.

📄 View solution
Exercise 2

Explain what happens to a running display manager when an administrator runs systemctl isolate multi-user.target on a desktop system currently in graphical.target, and why.

📄 View solution
Exercise 3

Explain, in terms of this chapter's own material, why booting with systemd.unit=rescue.target (grub1-4's own kernel parameter) can succeed even when something is broken elsewhere in the normal boot chain that would prevent reaching graphical.target or multi-user.target.

📄 View solution

Chapter 5 Quick Reference

  • A target is a named synchronization point — "reached" once everything it requires/wants has started
  • poweroff.target (0), rescue.target (1), multi-user.target (3), graphical.target (5), reboot.target (6) — direct legacy runlevel mapping
  • graphical.target Wants= multi-user.target — a strict superset, GUI on top of full multi-user mode
  • systemctl get-default/set-default — controlled by a symlink, the same mechanism as an individual unit's own WantedBy=
  • systemctl isolate TARGET — a live runlevel-style switch, the modern equivalent of telinit N
  • grub1-4's own systemd.unit=rescue.target works precisely because it skips graphical/multi-user's own much larger dependency set
  • isolate is immediately disruptive on a live system — never run casually