What systemd is: init, units, and services
A beginner-friendly explainer of systemd: what an init system is, what units and services are, and the everyday systemctl commands you meet on Arch.
level:Beginner
If you have installed Arch, you have already typed systemctl several times — to turn on networking, to start a display manager, to bring up audio. It is the single most-used command on a modern Linux box after cd and ls, and yet most people never stop to ask what it is actually talking to. The answer is systemd: the program that starts your system and manages everything running on it. This post explains what that means from the ground up, so the commands you copy from the wiki stop being magic incantations and start being obvious.
What an init system is
When the kernel finishes loading, it does one last thing before its boot job is done: it starts a single userspace program and hands control to it. That program is PID 1 — process ID 1, the very first process outside the kernel. Every other process on the system is descended from it, directly or indirectly. If PID 1 ever exits, the kernel panics, because there is nothing left to run.
PID 1 is the init system (short for initialisation). Its job is to bring the rest of userspace up: mount filesystems, start background services, get you to a login prompt, and — just as importantly — shut everything back down cleanly when you power off. You can confirm what is sitting on PID 1 yourself:
ps -p 1 -o comm=
On Arch, and on most mainstream distributions today, that prints systemd. Historically it would have printed init, referring to the old System V init (sysvinit), which started things one shell script at a time in a fixed order. systemd replaced that model. It is both the init system and a full service manager: it tracks every service it starts using kernel control groups, starts independent services in parallel to boot faster, and can start services on demand the first time something needs them. As the Arch Wiki puts it, systemd is "a suite of basic building blocks for a Linux system" that "provides a system and service manager that runs as PID 1 and starts the rest of the system."
What this looks like in motion is a short handoff: the kernel does its own setup, then launches exactly one program — systemd as PID 1 — and from there systemd walks a dependency graph until it reaches a named goal state. The kernel starts one process; that process starts everything else.
flowchart LR
A["kernel finishes boot"] --> B["starts PID 1<br/><i>systemd</i>"]
B --> C["reads unit dependencies"]
C --> D["starts required units<br/>in parallel"]
D --> E["reaches a target<br/><i>e.g. graphical.target</i>"]
If you come from another desktop, this role is familiar even if the name is not: systemd is the rough counterpart of the Service Control Manager on Windows or launchd on macOS — the one always-running supervisor that owns startup, shutdown, and the background services in between.
Units: the things systemd manages
systemd does not think in terms of "scripts" or "programs." It thinks in units. A unit is any resource systemd knows how to manage, described by a small plain-text configuration file. The file extension tells you the unit's type, and that type tells you what it manages. The ones you will actually meet:
.service— a process to run: a daemon, a one-shot setup task, anything that does something. This is by far the most common type and the one you interact with daily.NetworkManager.serviceandsshd.serviceare both services..target— a grouping and synchronisation point. A target does nothing on its own; it pulls in a set of other units so you can refer to "the whole graphical desktop" or "basic multi-user readiness" by one name. More on these below..socket— a network or IPC socket that systemd listens on for a service. When traffic arrives, systemd starts the matching.serviceon demand. This is "socket activation," and it is how something can appear to be always available without actually running until first use..timer— a scheduled trigger, systemd's replacement for cron jobs. A.timeractivates an associated.serviceon a schedule, either at a wall-clock time (OnCalendar=, just like cron) or relative to boot. Many maintenance tasks on Arch ship as timer/service pairs..mount— a filesystem mount point. systemd can generate these automatically from your/etc/fstab, which is why mounting is part of the boot graph rather than a separate step.
There are more unit types — .device, .path, .slice — but the five above cover almost everything a desktop user encounters. The unifying idea is that everything is a unit, and units can declare dependencies and ordering between each other. systemd reads that whole dependency graph and works out a correct, parallel order to bring things up.
Why so many types? Because "manage the system" really means managing several different kinds of thing — a process is not the same as a socket or a clock — and giving each kind its own file extension lets one tool reason about all of them uniformly. Here is the same five-way map as a picture, each with its one-line role. The extension tells you what the unit manages.
flowchart TD
U["unit<br/><i>anything systemd manages</i>"]
U --> S[".service<br/>a process to run"]
U --> T[".target<br/>a grouping / sync point"]
U --> K[".socket<br/>listen, start on demand"]
U --> M[".timer<br/>scheduled trigger"]
U --> N[".mount<br/>a filesystem mount point"]
The everyday commands
You manage units with systemctl. The handful you will use constantly:
sudo systemctl start NetworkManager # start it now (until reboot)
sudo systemctl stop NetworkManager # stop it now
systemctl status NetworkManager # is it running? recent log lines?
sudo systemctl enable NetworkManager # start it automatically on every boot
sudo systemctl disable NetworkManager # stop doing that
Note the distinction that trips up beginners: start is now, enable is forever. start runs the service this session and forgets about it on reboot. enable creates a symlink so the service comes up on every future boot, but does not touch the current session. You almost always want both, which is why the combined form exists and why the wiki uses it everywhere:
ℹ️ Noteenableandstartanswer two different questions.enablemakes the service come up on every boot;startruns it right now, this session.enable --nowdoes both in one step — which is why it is the form you see almost everywhere.
sudo systemctl enable --now NetworkManager
systemctl enable --now enables the unit and starts it in one step. This is the exact command you ran in the Arch install to get online, where NetworkManager runs as a system service — owned by the machine, started before any user logs in, shared by everyone.
The two halves answer two different questions — is it running right now? and should it come back after a reboot? — and they are independent, which is exactly why the combined form is so common. enable is about future boots; start is about this moment.
flowchart TD
A["systemctl enable --now NetworkManager"] --> B{"which part?"}
B -->|"enable"| C["runs on every future boot"]
B -->|"start"| D["runs right now, this session"]
C --> E["both together<br/><i>up now and after reboot</i>"]
D --> E
Not every service belongs to the machine, though. Some belong to you. Add --user and systemctl talks to a separate, per-user systemd instance that manages services scoped to your login session, with no sudo:
systemctl --user enable --now pipewire pipewire-pulse wireplumber
That is the audio command from the install. PipeWire is a per-user service because audio is inherently personal — it follows your session rather than running machine-wide. So the same install gives you both flavours side by side: NetworkManager as a system unit (sudo, machine-owned), PipeWire as a user unit (--user, no sudo, yours). That contrast is the whole system-vs-user distinction in two commands.
Targets, briefly (and the old runlevels)
If you used Linux years ago you may remember runlevels — numbered system states like "3" for multi-user text mode and "5" for the graphical desktop. systemd replaced runlevels with targets, which do the same job but with descriptive names. The rough mapping, per the systemd documentation: runlevel 3 corresponds to multi-user.target and runlevel 5 to graphical.target. systemd even ships compatibility aliases (runlevel3.target, and so on) so old habits keep working.
The difference is that a target is just another unit that pulls in a set of others. graphical.target depends on multi-user.target, which depends on basic.target — a dependency chain rather than a fixed numbered ladder. When your machine boots to a desktop, it is reaching graphical.target, and everything that target requires gets started along the way.
Where the logs go: journald
systemd captures the output of every service it manages into a single structured log called the journal, run by systemd-journald. Instead of hunting through scattered text files in /var/log, you query one place with journalctl. The single most useful invocation filters by unit:
journalctl -u NetworkManager # everything NetworkManager logged
journalctl -b # everything since this boot
On Arch the journal is persistent by default — it writes to /var/log/journal/ — so logs survive reboots. The systemd/Journal wiki page covers the rest. For now: when a service misbehaves, systemctl status <unit> shows the last few lines and journalctl -u <unit> shows the full history.
A note on the controversy
ℹ️ Note This section is an aside, not something you need to act on. systemd is the most-used init system on Linux and also the most argued-about; the calm summary below is here for context, not for any decision you have to make.
systemd is the most-used init system on Linux and also the most argued-about, so it is worth a calm paragraph. The project began in 2010 when Lennart Poettering and Kay Sievers at Red Hat set out to replace sysvinit, introduced in Poettering's "Rethinking PID 1" blog post. The recurring criticism is that systemd does too much: beyond starting processes it absorbed logging, device handling, network configuration, and more, which critics argue violates the Unix tradition of small tools that each do one thing. Defenders counter that systemd is modular internally and that solving boot, service supervision, and logging together produces a far more coherent and reliable system than a pile of shell scripts ever did. Both views have merit; the practical reality is that systemd won the mainstream, and learning it is simply learning how a modern Linux machine works. If the word daemon in all of this is unfamiliar, where the word "daemon" comes from explains both the term and the model managing it.
Where you meet this in the Arch install
You first run systemctl in part 3 of the install, enabling NetworkManager to get online, then your display manager (GDM or SDDM) to reach a graphical login, and PipeWire as a --user service for audio. Every one of those is the exact pattern described above: a unit, started now and enabled for future boots. If you want the wider context for where systemd sits in a Linux system, what Linux actually is frames the kernel-and-userspace split that PID 1 lives on top of, and the full Arch install companion ties the steps together.
A short close
systemd is PID 1: the first process the kernel starts and the parent of everything else, doubling as the service manager that keeps your system running. It models the world as units — services, targets, sockets, timers, mounts — and you drive them with systemctl, where enable decides what comes back on reboot and start decides what runs right now, optionally scoped to your user with --user. Targets replaced numbered runlevels, journald collects the logs, and the long-running debate over its scope does not change the fact that knowing these few commands is knowing how to operate a modern Linux box. The next time you type systemctl enable --now, you will know exactly what is on the other end.