linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Processes & resources/systemd-targets

kb/processes ── Processes & resources ── intermediate

systemd targets: runlevels the new way

A target is a `.target` unit that describes a desired system state as a set of dependencies. It replaces SystemV runlevels: `multi-user.target` ≈ runlevel 3, `graphical.target` ≈ runlevel 5.

view as markdownaka: target-unit, default-target, multi-user-target, graphical-target, runlevel

What a target is

A target is neither a process nor a service. It is a .target unit that does nothing on its own, but through Wants= / Requires= it pulls in a set of other units. Reaching a target means "every required service is up."

An analogy from SystemV: a target is like a runlevel, but it works through dependencies instead of numbered scripts in /etc/rc3.d/.

Mapping to SystemV runlevels

SystemV runlevelsystemd targetWhat it means
0poweroff.targetShutdown
1 / Srescue.targetSingle-user, FS mounted, root shell
1 (deeper)emergency.targetEmergency shell only, FS not mounted
2multi-user.targetMulti-user without NFS (historically)
3multi-user.targetCLI server: everything runs, no GUI
5graphical.targetServer plus display manager (GUI)
6reboot.targetReboot

The aliases runlevel3.target → multi-user.target are kept for backward compatibility with old scripts and the init 3 command.

default.target: where the system boots into

/etc/systemd/system/default.target is a symlink to the canonical target:

bash
ls -l /etc/systemd/system/default.target

▸/usr/lib/systemd/system/graphical.target

This is what systemd picks up at startup when the kernel cmdline does not pass systemd.unit=.... You do not need to change it by hand with ln -s. There is a command for it:

bash
systemctl get-default                            # current one
sudo systemctl set-default multi-user.target     # for servers without a GUI

System targets: the full boot chain

They form a dependency tree, going from low-level to high-level:

sysinit.target          ← mounts, swap, sysctl, journald
     ↓
basic.target            ← timers.target, sockets.target, slices.target
     ↓
multi-user.target       ← all the usual daemons (sshd, nginx, postgres)
     ↓
graphical.target        ← + display-manager.service (gdm/lightdm)
     ↓
default.target          ← symlink to one of the above

Alongside these there are "synchronization" targets:

  • network.target is reached when all network units are configured (this does NOT mean the host is online)
  • network-online.target is reached when the network is actually ready and an IP is assigned (for services that are useless without connectivity)
  • local-fs.target is reached when all local filesystems from mount-and-fstab are mounted
  • remote-fs.target is reached when all NFS/SMB mounts are in place
  • time-sync.target is reached when the clock is synchronized (see chrony-and-ntp)

How a target collects its units

Two mechanisms:

1) Through the [Install] section of a service. When you run systemctl enable nginx, a symlink is created:

/etc/systemd/system/multi-user.target.wants/nginx.service
 → /usr/lib/systemd/system/nginx.service

That .wants/ directory (and .requires/) is what the target picks up at startup.

2) Through the WantedBy= directive in the target file itself, for system targets.

bash
cat /usr/lib/systemd/system/graphical.target
# [Unit]
# Description=Graphical Interface
# Requires=multi-user.target
# Wants=display-manager.service
# After=multi-user.target display-manager.service
# AllowIsolate=yes

AllowIsolate=yes is critical. Without it a target cannot be made the default, and you cannot switch to it through isolate.

Switching between targets on the fly

bash
sudo systemctl isolate multi-user.target    # drop to CLI without a reboot
sudo systemctl isolate graphical.target     # bring the GUI back
sudo systemctl isolate rescue.target        # repair without a reboot
sudo systemctl rescue                       # same as isolate rescue.target
sudo systemctl emergency                    # emergency shell

isolate stops everything that the new target does NOT need and starts what it does. The name is odd, but that is the one.

Passing a target through GRUB at boot

If the system does not boot into default.target, you can override it once from GRUB. At the menu screen, press e to edit, and on the linux ... line append:

systemd.unit=rescue.target

Then Ctrl+X to boot. This applies to this boot only; the default is not changed.

Debugging: what a target pulls in

bash
systemctl list-units --type=target              # active targets
systemctl list-dependencies multi-user.target   # the tree of all units
systemctl list-dependencies --reverse nginx     # which targets nginx belongs to
systemctl cat multi-user.target                 # the resulting file

Creating your own target rarely makes sense, for example for a group of custom services that you switch on and off together. Most of the time WantedBy=multi-user.target in ordinary units is enough.

§ команды

bash
systemctl get-default

Which target the system boots into, usually multi-user or graphical

bash
sudo systemctl set-default multi-user.target

Make a server CLI-only. Saves resources, no display manager needed

bash
sudo systemctl isolate rescue.target

Drop to single-user mode on the fly (no reboot) for repairs

bash
systemctl list-dependencies multi-user.target

Show the whole tree of units a target pulls in, what actually starts

bash
systemctl list-units --type=target --all

All targets with their status, to see which ones are active right now

§ см. также

  • systemdsystemd: the init system and service managersystemd is the Linux init system: PID 1 that starts everything else, tracks dependencies, restarts what crashes, and collects the logs.
  • cmd-systemctlsystemctl: managing systemd services`systemctl` is the main CLI for managing systemd units: services, timers, mounts, and sockets. It replaces SysV init and `service` on modern distros.
  • systemd-unit-typessystemd unit typesA unit is a resource managed by systemd. The file extension equals the type: `.service` (daemon), `.socket` (lazy start on a socket), `.timer`, `.mount`, `.path`, `.slice`/`.scope` (cgroups), `.target` (a group).
  • systemd-drop-inssystemd drop-ins: override without editing the originalA drop-in is a `.conf` file in a `<unit>.d/` directory that merges into the unit file. It overrides any directive of a unit **without editing the original file** from the package.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies