systemctl

On this page 7

systemctl is the primary command-line interface to systemd, the init system and service manager used by most modern Linux distributions. In system initialization, it is the tool administrators use to start, stop, restart, enable, disable and inspect units such as services, sockets, timers, mounts and targets, and to change the overall system state, for example to reboot or switch to a rescue target.

systemctl does not run services itself. It sends requests over D-Bus to the systemd manager, process ID 1 for the system instance or a per-user manager with the --user option, and systemd carries out the job, tracks dependencies and records the result.

How systemctl communicates with systemd

Each systemctl command translates into a job that systemd queues and executes. A request such as systemctl start nginx.service asks the manager to bring the unit to the active state; systemd then resolves its dependencies, orders them according to After= and Before= directives, starts the required units first and reports success or failure.

The tool talks to the local manager by default, but it can address a remote host over SSH with -H user@host or a container with -M name. Read-only queries such as status work for ordinary users, while state-changing operations require root privileges or a polkit authorization.

StateMeaningCommandsPersists across reboot
Runtime stateWhether a unit is running nowstart, stop, restart, reloadNo
Enablement stateWhether a unit starts at boot or on triggerenable, disableYes
Masked stateUnit cannot be started at allmask, unmaskYes
Two kinds of state that systemctl manages

Separating these two dimensions is the most important concept for new administrators: enabling a service does not start it, and stopping a service does not disable it. The shortcut systemctl enable --now does both at once.

Essential systemctl commands

Most daily administration uses a small set of subcommands. The table groups them by purpose; unit names can omit the .service suffix, which systemctl adds automatically.

SubcommandPurposeTypical use
statusShows state, main PID, cgroup and recent log linesFirst step in troubleshooting
start / stop / restartChanges runtime stateApplying a new binary or recovering
reloadAsks the service to reread configurationWeb servers without dropping connections
enable / disableCreates or removes install symlinksControlling start at boot
mask / unmaskLinks the unit to /dev/nullPreventing any start, even as a dependency
daemon-reloadRereads all unit filesAfter editing or adding unit files
list-units / list-unit-filesLists loaded units or installed unit filesInventory and auditing
is-active / is-enabled / is-failedReturns state as an exit codeScripts and health checks
Frequently used subcommands

The edit subcommand creates a drop-in override under /etc/systemd/system/<unit>.d/, which changes selected directives without modifying the vendor unit in /usr/lib/systemd/system/. systemctl cat shows the effective unit including all drop-ins, and systemctl show prints every resolved property in machine-readable form.

Unit states and how to read status output

The status output combines the load state, the active state and a more detailed sub-state, followed by the last lines from the journal. Reading these fields correctly answers most questions about why a service is not running.

Field and valueMeaningTypical next step
loadedUnit file parsed successfullyNone
not-foundNo unit file with that nameCheck spelling or package installation
maskedUnit deliberately blockedUnmask if the block is unintended
active (running)Main process is aliveNone
active (exited)One-shot unit completed successfullyExpected for setup tasks
failedProcess exited with an error or timed outRead the journal, fix, reset-failed
activatingStart in progress or waitingCheck timeouts and dependencies
Common states shown by systemctl status

Because status shows only a few log lines, the full history comes from journalctl, for example journalctl -u nginx.service -b for the current boot. The two tools are designed to be used together.

Targets, power management and comparison with older tools

systemctl also controls system-wide state through targets, which replace SysVinit runlevels. systemctl get-default shows the boot target, set-default changes it, and isolate switches the running system to another target, stopping units that the new target does not require.

TaskSysVinit erasystemd era
Start a serviceservice nginx startsystemctl start nginx
Enable at bootchkconfig or update-rc.dsystemctl enable nginx
Change runleveltelinit 3systemctl isolate multi-user.target
Rebootshutdown -r nowsystemctl reboot
SuspendDistribution-specific scriptssystemctl suspend
systemctl compared with SysVinit commands

Many distributions keep the service command as a compatibility wrapper that forwards to systemctl, so older scripts continue to work.

The same tool manages per-user services with the --user flag, which controls a separate systemd instance running for each logged-in user. Combined with loginctl enable-linger, user services can keep running after logout, a common pattern for rootless containers and personal background jobs. systemctl also lists and controls systemd timers, the modern replacement for many cron jobs, through systemctl list-timers.

Common mistakes

Most systemctl problems in practice come from misunderstanding the state model rather than from bugs in systemd. The following mistakes appear repeatedly in production incidents and support requests.

  • Forgetting daemon-reload after editing a unit file, which leaves systemd running the old definition and prints a warning in status.
  • Editing vendor units directly in /usr/lib/systemd/system/, where package updates overwrite the change; drop-ins are the correct method.
  • Assuming enable starts the service immediately, or that disable prevents manual or dependency-driven starts; only mask does that.
  • Using restart where reload suffices, which drops active connections unnecessarily.
  • Ignoring the failed state after fixing a problem; systemctl reset-failed clears it and resets start-rate limits.

In simple terms

A Linux computer runs many background programs, such as a web server, a database or the clock synchronization service. systemctl is the remote control for all of them.

With one command an administrator can turn a program on or off right now, decide whether it should start automatically when the computer boots, or ask why it stopped working. Behind the scenes, systemctl passes these requests to systemd, which does the actual work.

A practical example

An administrator installs a web server on a new Linux virtual machine. The command systemctl enable --now nginx starts it and registers it to start at every boot. After changing the configuration to add a new site, the administrator runs nginx -t and then systemctl reload nginx, so visitors with open connections are not interrupted.

A week later the site is down after a reboot. systemctl status nginx shows failed with an error about an address already in use. The journal reveals that another web server was enabled by mistake. The administrator runs systemctl disable --now apache2, then systemctl restart nginx, and the site is back within a minute, with the cause documented.