Tame systemd without memorizing everything
Understand services, units, logs, dependencies, and timers through a small set of practical commands and mental models.
systemd is easier when you treat it as a manager of units and state, not as a bag of commands. A service is one kind of unit. Timers, sockets, mounts, and targets are others.
The five commands you will use most
systemctl status sshd
systemctl start sshd
systemctl stop sshd
systemctl restart sshd
systemctl enable --now sshd
start affects the current boot. enable creates the relationships needed to start a unit on future boots. enable --now does both. A unit can be enabled but currently stopped, or running but not enabled.
Some distributions call the OpenSSH unit ssh.service; others use sshd.service. Let completion help you: type systemctl status ssh and press Tab.
Status first, logs second
When a service fails, do not immediately edit its configuration. Read the state:
systemctl status nginx --no-pager
journalctl -u nginx --since "20 minutes ago"
For the current boot only:
journalctl -u nginx -b
Follow new messages while reproducing a problem:
journalctl -fu nginx
The journal is indexed metadata, not merely one giant text file. Filter early by unit, boot, priority, or time to avoid drowning in unrelated messages.
Read the unit that systemd actually sees
Packages commonly place unit files under /usr/lib/systemd/system or /lib/systemd/system. Local administrator overrides belong under /etc/systemd/system. Do not edit vendor files directly; upgrades can replace them.
systemctl cat nginx
systemctl show nginx -p FragmentPath -p ActiveState -p SubState
Create an override safely:
sudo systemctl edit nginx
For example, a service environment override might contain:
[Service]
Environment="APP_MODE=production"
After changing unit definitions, reload the manager and restart the affected service:
sudo systemctl daemon-reload
sudo systemctl restart nginx
Understand dependencies without drawing the whole graph
Use these when ordering or startup behavior surprises you:
systemctl list-dependencies nginx
systemctl list-dependencies --reverse network-online.target
systemd-analyze critical-chain
After= controls ordering; it does not automatically pull another unit in. Wants= and Requires= express dependencies. Most custom units need only a small, explicit set of relationships.
Prefer timers to cron for system jobs
A timer has a matching service. This separation makes the job testable and its logs easy to find.
# /etc/systemd/system/backup-home.service
[Unit]
Description=Back up home directory
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/backup-home
# /etc/systemd/system/backup-home.timer
[Unit]
Description=Run home backup every night
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=15m
[Install]
WantedBy=timers.target
Validate and activate it:
sudo systemd-analyze verify /etc/systemd/system/backup-home.*
sudo systemctl enable --now backup-home.timer
systemctl list-timers
Persistent=true means a missed calendar run can be triggered after the machine comes back online. The randomized delay prevents many machines from starting the same job simultaneously.
The recovery sequence
When something breaks: inspect status, filter the journal, view the effective unit with systemctl cat, test the underlying command manually when safe, fix the smallest cause, then restart and verify. That sequence is more valuable than memorizing fifty subcommands.
Official references
- systemd project documentation
man systemctl,man systemd.unit,man systemd.serviceman journalctl,man systemd.timer
