Systemd Units: Unit, Service, Target, Start vs Enable¶
Mental model¶
A unit file declares what to manage. Start/stop controls runtime. Enable/disable controls boot. Wants/requires declare dependencies. After/before declare ordering. These are orthogonal axes.
What it looks like¶
"Enable the service" — expecting it to start immediately.
What it really is¶
Unit file: a declarative INI-style config in /etc/systemd/system/
or /usr/lib/systemd/system/. Tells systemd what a thing is and how
to manage it. Every managed object is a unit.
Unit types:
- service — a process (ExecStart, restart policy, resource limits)
- target — a synchronization point grouping other units (like a
runlevel)
- timer — triggers a service on a schedule (replaces cron)
- socket — socket activation (start service on connection)
- mount — manages a mount point
- path, slice, scope, swap — other managed objects
start/stop: changes runtime state now. Transient. Lost on reboot unless the unit is enabled.
enable/disable: creates or removes a symlink in a target's
.wants/ directory. Controls whether the unit starts at boot. Does
NOT affect current runtime state.
wants: weak dependency. "Start X if possible, but don't fail me
if X fails." Creates a .wants/ symlink.
requires: hard dependency. "X must succeed or fail me too."
after/before: ordering directives. "Start me after X is started."
No dependency implied — if X isn't otherwise pulled in, after alone
won't start it.
Why it seems confusing¶
enabledoes NOT start the service.startdoes NOT enable it.wantsdoes NOT imply ordering.afterdoes NOT imply dependency.- These are two orthogonal axes: dependency (wants/requires) and ordering (after/before). You usually need both.
What actually matters¶
systemctl enable --now foo= enable + start in one command.Wants=+After=is the common pattern: depend on it AND order after it.Requires=withoutAfter=starts both in parallel — the dependent unit may start before its requirement is ready.- Targets group units.
multi-user.targetis roughly "system ready for non-graphical use." Enabling a service usually symlinks it intomulti-user.target.wants/.
Common mistakes¶
- Running
systemctl enable fooand wondering why it's not running yet (needstartor--now). - Using
Requires=withoutAfter=and getting a race condition. - Using
Wants=thinking it guarantees ordering (it doesn't). - Editing unit files without running
systemctl daemon-reload. - Confusing
systemctl restart(stop+start) withsystemctl reload(send SIGHUP, re-read config without stopping).
Small examples¶
Enable vs start:
systemctl enable nginx # symlink created, starts on next boot
systemctl status nginx # inactive (dead) — not started yet
systemctl start nginx # running now, but won't survive reboot
systemctl enable --now nginx # both: symlink + start immediately
Wants vs requires:
# Unit A wants B (weak):
# If B fails to start, A starts anyway.
# Unit A requires B (hard):
# If B fails to start, A is not started.
# Neither implies ordering. Add After=B.service for sequencing.
Checking unit relationships:
One-line summary¶
Units declare what to manage; start/enable are orthogonal; wants/requires and after/before are orthogonal.