systemd is the init system: the first process the kernel starts (PID 1, see The Boot Process and Process Lifecycle), responsible for starting everything else and keeping track of it afterward.

Units and targets

systemd's core concept is the unit - a configuration file describing something to manage. The most common unit type is .service, but there are others: .mount, .socket, .timer (see Cron and Scheduled Tasks for how timers compare to cron), and .target, which groups other units together as a named milestone (multi-user.target, graphical.target) rather than doing anything itself.

Managing services with systemctl

sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx     # re-read config without a full restart, if supported
systemctl status nginx
● nginx.service - A high performance web server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2026-08-27 09:14:02 UTC; 1 day 4h ago
   Main PID: 1050 (nginx)
      Tasks: 3 (limit: 4915)
     Memory: 5.2M
        CPU: 890ms
     CGroup: /system.slice/nginx.service
             ├─1050 nginx: master process
             ├─1051 nginx: worker process
             └─1052 nginx: worker process

start/stop act now; they don't affect whether a service comes back on the next boot. That's controlled separately:

sudo systemctl enable nginx    # start automatically at boot
sudo systemctl disable nginx   # don't
sudo systemctl enable --now nginx  # both: enable and start immediately

A minimal unit file

[Unit]
Description=My background worker
After=network.target

[Service]
ExecStart=/usr/local/bin/worker.py
Restart=on-failure
User=worker

[Install]
WantedBy=multi-user.target
  • [Unit] - metadata and ordering (After= doesn't create a dependency by itself, just an ordering constraint - pair it with Requires= or Wants= if the service genuinely needs the target to be up)
  • [Service] - how to run it, and what to do if it exits unexpectedly (Restart=on-failure is a common choice for anything meant to stay up)
  • [Install] - what enable actually wires up: which target pulls this unit in

Custom unit files typically go in /etc/systemd/system/. After adding or editing one, reload systemd's view of unit files before it takes effect:

sudo systemctl daemon-reload

Reading service logs

Every service managed by systemd has its output captured by journald automatically - no separate log file configuration needed:

journalctl -u nginx -f

See Logs and journald for the full journalctl reference.

Distro and version notes

systemd is the default init system on Debian, Ubuntu, Fedora, RHEL/CentOS, Arch, openSUSE, and most others as of any reasonably current release. Notable holdouts by choice include Alpine Linux and Gentoo (both default to OpenRC), and Devuan (a Debian derivative that deliberately ships without systemd). If a command like systemctl doesn't exist on a system you're working on, check cat /proc/1/comm to confirm what's actually running as PID 1 before assuming systemd conventions apply.