Guides

systemctl commands: listing, restarting and checking services

systemctl list-units, status, start/stop/restart, enable --now, is-active and list-timers, with real output for each — and where systemctl stops and journalctl takes over.

Published ~7 min read

Short answer: systemctl list-units --type=service lists every service systemd currently knows about and its state; systemctl restart NAME restarts one; journalctl -u NAME is the matching log command, not systemctl itself. The table below covers the commands people reach for most, with the real output of each one.

TaskCommand
List running servicessystemctl list-units --type=service
List every installed unit (running or not)systemctl list-unit-files --type=service
Status of one servicesystemctl status nginx
Start / stop / restartsystemctl start|stop|restart nginx
Re-read config without a restartsystemctl reload nginx
Start at boot / stop starting at bootsystemctl enable|disable nginx
Enable and start in one commandsystemctl enable --now nginx
Is it set to start at boot?systemctl is-enabled nginx
Is it running right now?systemctl is-active nginx
List failed unitssystemctl --failed
Overall system healthsystemctl is-system-running
List active timers (cron-like jobs)systemctl list-timers
Reload systemd itself after editing a unit filesystemctl daemon-reload

Listing services: list-units vs list-unit-files

These two commands answer different questions, and mixing them up is the most common confusion with systemctl:

running right now
systemctl list-units --type=service --no-pager
Example output (shortened)
UNIT                      LOAD   ACTIVE SUB     DESCRIPTION
cron.service              loaded active running Regular background program processing daemon
nginx.service             loaded active running A high performance web server
ssh.service               loaded active running OpenBSD Secure Shell server

3 loaded units listed.
installed, whether running or not
systemctl list-unit-files --type=service --no-pager
Example output (shortened)
UNIT FILE                     STATE           PRESET
nginx.service                 enabled         enabled
mysql.service                 disabled        enabled
bluetooth.service             masked          enabled

list-units without --all hides inactive and dead units, so a service that exists but never started is invisible there; add --all to see it, or use list-unit-files directly, which always shows everything installed. STATE in the second table is the boot setting (enabled, disabled, static for a unit nothing enables directly, masked for one actively blocked from starting), not whether it is running right now.

systemctl status: reading the output

systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-10-14 08:02:11 UTC; 3h 12min ago
       Docs: man:nginx(8)
    Process: 612 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 701 (nginx)
      Tasks: 3 (limit: 4617)
     Memory: 5.2M
        CPU: 312ms
     CGroup: /system.slice/nginx.service
             ├─701 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             ├─702 "nginx: worker process"
             └─703 "nginx: worker process"

Oct 14 08:02:11 vmheaven systemd[1]: Starting nginx.service - A high performance web server...
Oct 14 08:02:11 vmheaven systemd[1]: Started nginx.service - A high performance web server...
  • Loaded shows the unit file’s path and whether it is enabled (will start at boot) — useful on its own, without a separate is-enabled call.
  • Active is the real state: active (running) for a service with a running process, active (exited) for a one-shot job that finished successfully and stays “active”, failed when it crashed or exited with an error, inactive (dead) when it is simply stopped.
  • The last lines are the newest journal entries for this unit — the same ones journalctl -u nginx shows, just the tail of them. Scroll with the pager (q to quit) or add --no-pager to print everything at once.

A failed service

Example output
Active: failed (Result: exit-code) since Tue 2026-10-14 11:04:02 UTC; 2min ago
Process: 1840 ExecStart=/usr/local/bin/myapp (code=exited, status=1/FAILURE)

systemctl --failed lists every unit in this state across the whole system in one call, which is the quickest way to notice something broke without checking each service by name. Reading past the exit code into what the program actually printed is in journalctl.

restart vs reload vs reload-or-restart

CommandDoesUse when
systemctl restart NAMEStops the service fully, then starts it again — new process, brief downtimeA config change the service only reads at startup, or it is stuck
systemctl reload NAMEAsks the running process to re-read its config, no restart — only works if the unit defines ExecReload=nginx, and anything else whose unit supports it
systemctl reload-or-restart NAMEreload if the unit supports it, restart otherwiseA safe default when you are not sure which the unit has

systemctl cat NAME prints the unit file itself, so systemctl cat nginx | grep ExecReload tells you directly whether a plain reload will work before you try it.

enable, disable and the boot-time confusion

start/stop act now; enable/disable change only what happens at the next boot. Running one without the other is the single most common systemctl mistake:

  • systemctl start nginx alone: running now, but back off after a reboot if it was never enabled.
  • systemctl enable nginx alone: will start at the next boot, but not running right now until you start it or reboot.
  • systemctl enable --now nginx: both at once — the one to reach for after installing something new.

systemctl is-enabled nginx and systemctl is-active nginx answer the two questions separately and are the pair to use in a script, since both exit with status 0 only when the answer is yes.

systemctl has no log viewer — that is journalctl

systemctl status shows only the last handful of lines. For the full log of one service, everything since boot, or a live follow, the command is journalctl, covered in full in the journalctl guide:

the systemctl ↔ journalctl pair
systemctl status myapp          # quick look, last few lines
journalctl -u myapp              # the full log for this unit
journalctl -u myapp -f           # follow it live
journalctl -u myapp --since today

systemctl list-timers: systemd’s cron

systemctl list-timers --all
NEXT                         LEFT       LAST                          PASSED  UNIT                     ACTIVATES
Wed 2026-10-15 03:00:00 UTC  11h left   Tue 2026-10-14 03:00:00 UTC   13h ago backup.timer             backup.service
Wed 2026-10-15 00:00:00 UTC  8h left    -                             -       apt-daily.timer          apt-daily.service

A timer unit (backup.timer) is paired with a service unit of the same name (backup.service) that actually runs the job; enable --now the timer, not the service, or the job only ever runs once, immediately. See creating a systemd service for writing both files, and crontab for the older cron-based way to schedule jobs that still works and is simpler for a single quick job.

systemctl --user: your own services, not root’s

Every command above manages the system instance by default. Add --user to manage services that run as your own login instead, with no sudo:

Linux
systemctl --user status myapp
systemctl --user enable --now myapp

A user service only keeps running while that user is logged in, unless you also run loginctl enable-linger yourname once as root. Run as root with sudo -u alice instead of a real login and it fails with Failed to connect to bus — systemctl --user --machine=alice@.host status reaches it from there instead.

When do I need systemctl daemon-reload?

Only after editing a unit file itself — /etc/systemd/system/myapp.service or a drop-in under myapp.service.d/ — never after changing the application’s own config file. Skipping it is why a change to a unit file sometimes seems to do nothing: systemd is still running the old definition from memory.

after editing a .service file
sudo systemctl daemon-reload
sudo systemctl restart myapp

systemctl: command not found

That error means the machine is not running systemd at all — a Docker container, a WSL distribution without systemd switched on, or Alpine’s OpenRC — and the fix there is the service manager that machine really has, not systemctl. The full decision tree for each case is in systemctl: command not found.

Frequently asked

How do I list all services with systemctl?

systemctl list-units --type=service shows services currently loaded (add --all to include inactive ones); systemctl list-unit-files --type=service shows every installed service and whether it is enabled at boot, regardless of whether it is running right now. They answer different questions and are easy to mix up.

What is the difference between systemctl restart and systemctl reload?

restart stops the process and starts a new one, with a brief interruption and everything re-read from scratch. reload asks the running process to re-read its configuration without stopping it, but only works if the unit defines ExecReload= — nginx does, many simple services do not. reload-or-restart does whichever the unit supports.

Why is my service running but not starting at boot (or the reverse)?

start/stop act immediately; enable/disable only change what happens at the next boot. Running one without the other is the most common systemctl mistake — systemctl enable --now does both together, which is the command to use right after installing something new.

Where do I see a service's logs with systemctl?

systemctl itself does not log anything — journalctl -u SERVICE does, and systemctl status SERVICE shows only its last few lines as a preview. journalctl -u SERVICE -f follows a service's log live.

Related articles

All guides