systemd is the service manager used by most current Linux distributions. Its systemctl command controls services and other unit types, including sockets, timers, mounts, paths, devices, and targets.
Official references:
The examples use nginx.service. Replace it with the unit installed on your system.
Check the systemd Version
Display the installed systemd version and enabled features.
systemctl --version
Check whether systemd is PID 1.
ps -p 1 -o pid,comm,args
Display the overall manager status.
systemctl status --no-pager
Understand Unit Names
A complete unit name contains a suffix that identifies its type:
| Unit type | Example | Purpose |
|---|---|---|
| Service | nginx.service |
Daemon or process |
| Socket | ssh.socket |
Socket-based activation |
| Timer | fstrim.timer |
Scheduled activation |
| Mount | home.mount |
Filesystem mount |
| Path | example.path |
Path-based activation |
| Target | multi-user.target |
Group of units and boot state |
For many service commands, systemctl adds .service when the suffix is omitted. Writing the complete name makes scripts and documentation clearer.
Start, Stop, and Restart a Service
Start a service now.
sudo systemctl start nginx.service
Stop it now.
sudo systemctl stop nginx.service
Restart it even if it is currently inactive.
sudo systemctl restart nginx.service
Reload the application’s configuration without restarting its process. This succeeds only when the unit implements a reload operation.
sudo systemctl reload nginx.service
Reload the service when supported, or restart it otherwise.
sudo systemctl reload-or-restart nginx.service
Restart the service only if it is already running.
sudo systemctl try-restart nginx.service
systemctl daemon-reload has a different purpose: it makes the systemd manager reread unit files and dependency definitions. It does not reload an application’s own configuration and does not restart running services.
sudo systemctl daemon-reload
Enable or Disable Automatic Startup
Enabling and starting are separate operations. enable creates the links described by the unit’s [Install] section so it can be activated during boot or by another unit; it does not start the service unless --now is included.
Enable a service for future boots.
sudo systemctl enable nginx.service
Enable and start it in one operation.
sudo systemctl enable --now nginx.service
Disable future automatic startup without stopping the currently running service.
sudo systemctl disable nginx.service
Disable and stop it.
sudo systemctl disable --now nginx.service
Do not manually create links under a target’s .wants directory. systemctl enable reads the unit metadata, creates the correct links, and reloads the manager configuration.
Mask or Unmask a Unit
Masking prevents every form of activation, including manual starts and dependency-based starts. Use it only when a service must not run.
sudo systemctl mask nginx.service
Mask and stop the service immediately.
sudo systemctl mask --now nginx.service
Remove the mask before enabling or starting the unit again.
sudo systemctl unmask nginx.service
Check Service State
Show a human-readable status report with recent log messages.
systemctl status nginx.service
Prevent the output from opening a pager and show untruncated lines.
systemctl status nginx.service --no-pager --full
Use state-check commands in scripts. They print a state and return zero only when the requested condition is true.
systemctl is-active nginx.service
systemctl is-enabled nginx.service
systemctl is-failed nginx.service
Check only the exit status in a shell condition.
if systemctl is-active --quiet nginx.service; then echo running; else echo stopped; fi
An enabled service can be inactive, and an active service can be disabled. The first state controls future activation; the second describes its current runtime state.
Inspect Unit Properties and Files
Display every runtime property known to systemd.
systemctl show nginx.service
Select the most useful properties for troubleshooting.
systemctl show nginx.service --property=LoadState,ActiveState,SubState,UnitFileState,MainPID,Result,ExecMainCode,ExecMainStatus,FragmentPath,DropInPaths
Display the vendor unit file and every applied drop-in in precedence order.
systemctl cat nginx.service
Show the unit’s vendor file path.
systemctl show nginx.service --property=FragmentPath --value
Common system-unit locations are:
| Directory | Purpose |
|---|---|
/etc/systemd/system/ |
Local administrator units and overrides; highest persistent priority |
/run/systemd/system/ |
Runtime units and overrides removed at reboot |
/usr/lib/systemd/system/ |
Vendor or package-provided units |
/lib/systemd/system/ |
Vendor path used by some distributions |
Avoid editing package files under /usr/lib or /lib because upgrades can replace them.
List Services and Unit Files
List currently loaded units. Without --all, inactive units are normally omitted.
systemctl list-units
systemctl list-units --type=service
systemctl list-units --type=service --all
List failed units.
systemctl --failed
List installed unit files and their enablement state, including units that are not currently loaded.
systemctl list-unit-files
systemctl list-unit-files --type=service
systemctl list-unit-files --type=service --state=enabled
List jobs that systemd is currently starting or stopping.
systemctl list-jobs
Check the overall system state. Common results include running, degraded, starting, and maintenance.
systemctl is-system-running
Inspect Dependencies and Ordering
Display the units that the selected service depends on.
systemctl list-dependencies nginx.service
Include all dependency levels.
systemctl list-dependencies nginx.service --all
Display reverse dependencies: units that depend on the selected service.
systemctl list-dependencies nginx.service --reverse
Dependency relationships and start order are different concepts. Requires= and Wants= express dependency strength, while After= and Before= control ordering.
Read Service Logs
Show all retained messages for a service.
sudo journalctl -u nginx.service
Show the last 100 messages from the current boot without a pager.
sudo journalctl -u nginx.service -b -n 100 --no-pager
Follow new messages while reproducing a problem.
sudo journalctl -u nginx.service -n 50 -f
Edit a Service Safely
Use a drop-in to override a package-provided unit. This preserves the vendor file and survives package upgrades.
sudo systemctl edit nginx.service
For example, add restart behavior and a 1 GiB memory throttle with a 1536 MiB hard limit:
[Service]
Restart=on-failure
RestartSec=5s
MemoryHigh=1G
MemoryMax=1536M
Saving systemctl edit installs the drop-in under /etc/systemd/system/nginx.service.d/ and reloads the systemd manager. Restart the service when the changed setting applies only to a new process.
sudo systemctl restart nginx.service
Revert every local drop-in and full-file override created for the unit.
sudo systemctl revert nginx.service
If a unit file is edited manually, validate it and reload the manager before restarting the service.
sudo systemd-analyze verify /etc/systemd/system/example.service
sudo systemctl daemon-reload
sudo systemctl restart example.service
Set Resource Limits
Set persistent cgroup v2 properties without manually editing a drop-in. The changes apply immediately when possible and are saved for future starts.
sudo systemctl set-property nginx.service CPUWeight=200 MemoryHigh=1G MemoryMax=1536M
Use --runtime to keep a test change only until reboot.
sudo systemctl set-property --runtime nginx.service CPUWeight=200 MemoryHigh=1G
Inspect the effective properties.
systemctl show nginx.service --property=CPUWeight,MemoryHigh,MemoryMax,ControlGroup
CPUWeight is the current cgroup v2 replacement for the legacy CPUShares setting. A weight affects relative CPU distribution during contention; it is not a hard CPU limit. Use CPUQuota= when a hard bandwidth limit is required. MemoryHigh= is the preferred throttling control, while MemoryMax= is a last line of defense that can trigger an out-of-memory kill inside the unit.
Create a Custom Service
Create custom system units under /etc/systemd/system/. The example below runs an existing application as a dedicated unprivileged account.
sudoedit /etc/systemd/system/example.service
[Unit]
Description=Example application service
Wants=network-online.target
After=network-online.target
[Service]
Type=exec
User=example
Group=example
WorkingDirectory=/opt/example
ExecStart=/opt/example/bin/example
Restart=on-failure
RestartSec=5s
NoNewPrivileges=yes
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
Use network-online.target only when the application requires a configured network during startup. Many network services can start after network.target or without an explicit network ordering rule.
Systemd does not apply shell syntax to ExecStart by default. Use an absolute executable path and pass arguments directly. Do not add a shell solely for environment-variable expansion or redirection unless the service genuinely requires shell behavior.
Validate, load, enable, and start the unit.
sudo systemd-analyze verify /etc/systemd/system/example.service
sudo systemctl daemon-reload
sudo systemctl enable --now example.service
systemctl status example.service --no-pager --full
The example account, group, working directory, and executable must exist before starting the service.
Manage Template Instances
A template such as worker@.service can create multiple service instances. %i expands to the instance name inside the template.
[Unit]
Description=Worker instance %i
[Service]
Type=exec
ExecStart=/opt/example/bin/worker --instance %i
Restart=on-failure
[Install]
WantedBy=multi-user.target
Enable and start instance 1.
sudo systemctl enable --now worker@1.service
Manage another instance independently.
sudo systemctl start worker@2.service
sudo systemctl status worker@2.service
Manage User Services
User services run under the current user’s service manager and do not require root access. Store custom user units in ~/.config/systemd/user/.
mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/example.service
systemctl --user daemon-reload
systemctl --user enable --now example.service
systemctl --user status example.service
journalctl --user -u example.service
By default, a user’s manager may stop after the last login session ends. An administrator can enable lingering when that user’s services must continue without an active login.
sudo loginctl enable-linger username
Recover a Failed Service
Inspect status, logs, the recorded exit result, and the unit definition.
systemctl status nginx.service --no-pager --full
sudo journalctl -u nginx.service -b -p warning -n 100 --no-pager
systemctl show nginx.service --property=Result,ExecMainCode,ExecMainStatus,Restart,StartLimitBurst
systemctl cat nginx.service
After fixing the cause, clear the failed state and start the unit again.
sudo systemctl reset-failed nginx.service
sudo systemctl start nginx.service
If the message says the start request was repeated too quickly, fix the underlying crash before using reset-failed; clearing the counter alone does not correct the service.
Send a Signal to a Service
systemctl kill sends a signal to processes in a unit. Normal service shutdown should use systemctl stop so the unit’s configured stop behavior and timeout are honored.
Send SIGHUP only to the main process when an application documents that signal as a configuration reload request.
sudo systemctl kill --kill-whom=main --signal=SIGHUP nginx.service
Manage the Default Target
Display the target used for a normal boot.
systemctl get-default
Set a text-oriented multi-user boot.
sudo systemctl set-default multi-user.target
Set a graphical boot.
sudo systemctl set-default graphical.target
List installed and currently loaded targets.
systemctl list-unit-files --type=target
systemctl list-units --type=target --all
Traditional runlevel aliases commonly map as follows, although distribution presets can differ:
| Runlevel | systemd target |
|---|---|
| 0 | poweroff.target |
| 1 | rescue.target |
| 2, 3, 4 | multi-user.target |
| 5 | graphical.target |
| 6 | reboot.target |
Switch the running system to another target with isolate. Units not required by the new target can be stopped, so use a local console before isolating a remote server.
sudo systemctl isolate multi-user.target
Enter rescue or emergency mode from a local console.
sudo systemctl rescue
sudo systemctl emergency
Power and Sleep Commands
The following commands affect the whole machine and can disconnect users or interrupt work.
sudo systemctl reboot
sudo systemctl poweroff
sudo systemctl suspend
sudo systemctl hibernate
sudo systemctl hybrid-sleep
sudo systemctl suspend-then-hibernate
Hibernate and hybrid sleep require supported hardware, sufficient swap, and a correctly configured resume path. Check the journal if the machine returns immediately or fails to resume.