systemctl is the primary command for interacting with systemd —
the init system and service manager on all modern Linux distributions. It controls services,
targets, timers, mounts, sockets, and more. If you need to start it, stop it, check it,
or schedule it — systemctl is how you do it.
📚 This page is a quick-reference companion. For deep-dive coverage see:
systemctl Complete Reference |
Creating systemd Service Units
Unit Types
.service
Daemons and programs — the most common type
.timer
Scheduled tasks — modern cron replacement
.target
Grouping units — analogous to runlevels
.socket
Socket-activated services
.mount
Filesystem mount points
.path
Path-based activation
.slice
Resource control groups
.scope
Externally created processes
Syntax note: When working with
.service units you can
omit the extension — systemctl status sshd and
systemctl status sshd.service are equivalent.
Service Management
Start · Stop · Restart · Reload
| Command | What it does |
|---|---|
| systemctl start sshd | Start the service now (does not affect boot) |
| systemctl stop sshd | Stop the service now |
| systemctl restart sshd | Stop then start — drops all connections |
| systemctl reload sshd | Reload config without stopping (if supported) |
| systemctl reload-or-restart sshd | Reload if supported, restart otherwise |
| systemctl try-restart sshd | Restart only if currently running |
| systemctl kill sshd | Send signal to all processes of the unit |
Enable · Disable (Boot Persistence)
| Command | What it does |
|---|---|
| systemctl enable sshd | Enable at boot (creates symlink) |
| systemctl disable sshd | Disable at boot (removes symlink) |
| systemctl enable --now sshd | Enable AND start immediately |
| systemctl disable --now sshd | Disable AND stop immediately |
| systemctl reenable sshd | Disable then re-enable (reset symlinks) |
| systemctl mask sshd | Prevent start completely — even manually |
| systemctl unmask sshd | Remove mask |
💡 enable --now is the pattern you want for most provisioning work —
one command starts the service and ensures it survives reboots.
⚠️ mask vs disable:
disable stops autostart but still
allows manual start. mask symlinks the unit to
/dev/null — nothing can start it until unmasked. Use mask for services
you want completely locked out (e.g., telnet.socket).
Status and Inspection
Checking Status
| Command | What it does |
|---|---|
| systemctl status sshd | Full status — state, PID, recent journal lines |
| systemctl is-active sshd | Prints "active" or "inactive" — good for scripts |
| systemctl is-enabled sshd | Prints "enabled", "disabled", "masked" |
| systemctl is-failed sshd | Returns 0 if unit is in failed state |
| systemctl show sshd | All properties of the unit (machine-readable) |
| systemctl show -p MainPID sshd | Show a single property |
| systemctl cat sshd | Display the unit file as loaded |
Listing Units
| Command | What it does |
|---|---|
| systemctl list-units | All active units |
| systemctl list-units --all | All units including inactive |
| systemctl list-units --type=service | Services only |
| systemctl list-units --state=failed | Failed units only — first stop after boot |
| systemctl list-unit-files | All installed unit files and their state |
| systemctl list-unit-files --type=service | Service unit files only |
| systemctl list-timers | All timers with next/last trigger times |
| systemctl list-sockets | All socket units |
| systemctl list-dependencies sshd | Dependency tree for a unit |
# Practical — see what failed on boot systemctl list-units --state=failed # Find all enabled services systemctl list-unit-files --type=service --state=enabled # Script-friendly status check systemctl is-active nginx && echo "running" || echo "not running"
Configuration
After Editing Unit Files
| Command | What it does |
|---|---|
| systemctl daemon-reload | Re-read all unit files — required after any edit |
| systemctl edit sshd | Open a drop-in override (preferred over editing originals) |
| systemctl edit --full sshd | Edit a full copy of the unit file |
| systemctl revert sshd | Remove overrides, restore original unit |
Unit file locations:
/lib/systemd/system/ — distro-provided (do not edit)/etc/systemd/system/ — your overrides and custom units (edit here)/etc/systemd/system/sshd.service.d/ — drop-in override directory
💡 Always
daemon-reload after creating or editing any unit file.
systemd reads unit files at load time — without a reload it will keep using the old version.
Targets (Runlevels)
Common Targets
| Target | SysV Equivalent | Description |
|---|---|---|
| poweroff.target | runlevel 0 | Shut down and power off |
| rescue.target | runlevel 1 | Single-user rescue mode |
| multi-user.target | runlevel 3 | Multi-user, no GUI — typical server default |
| graphical.target | runlevel 5 | Multi-user with GUI |
| reboot.target | runlevel 6 | Reboot |
| emergency.target | — | Minimal emergency shell |
Target Commands
| Command | What it does |
|---|---|
| systemctl get-default | Show current default boot target |
| systemctl set-default multi-user.target | Set default boot target |
| systemctl isolate rescue.target | Switch to target now (stops other units) |
Power Management
| Command | What it does |
|---|---|
| systemctl poweroff | Shut down and power off |
| systemctl reboot | Reboot |
| systemctl halt | Halt (may not power off) |
| systemctl suspend | Suspend to RAM |
| systemctl hibernate | Suspend to disk |
| systemctl rescue | Drop to single-user rescue mode |
| systemctl emergency | Drop to emergency shell (minimal) |
Essential Companion — journalctl
systemctl status shows a few log lines. For the full picture use journalctl:
# All logs for a unit journalctl -u sshd # Follow logs live (like tail -f) journalctl -u sshd -f # Logs since last boot journalctl -u sshd -b # Last 50 lines journalctl -u sshd -n 50 # Kernel messages only journalctl -k # All errors and above, this boot journalctl -b -p err
Common Workflows
Deploy a New Service
# 1. Place unit file sudo cp myapp.service /etc/systemd/system/ # 2. Reload systemd sudo systemctl daemon-reload # 3. Enable and start sudo systemctl enable --now myapp # 4. Verify systemctl status myapp
Diagnose a Failed Service
# See what failed systemctl list-units --state=failed # Get details systemctl status myapp # Read the full log journalctl -u myapp -b --no-pager # After fixing — reset failed state and restart sudo systemctl reset-failed myapp sudo systemctl start myapp
Override a Vendor Unit File
# Opens editor for a drop-in override — safe, non-destructive sudo systemctl edit sshd # Example override content to increase connection limit: # [Service] # LimitNOFILE=65536 # Reload after saving sudo systemctl daemon-reload sudo systemctl restart sshd
💡 Never edit files in
/lib/systemd/system/ directly —
package updates will overwrite your changes. Always use
systemctl edit to create a drop-in, or copy to
/etc/systemd/system/ and edit there.
Boot Analysis
| Command | What it does |
|---|---|
| systemd-analyze | Total boot time summary |
| systemd-analyze blame | Per-unit boot time, sorted slowest first |
| systemd-analyze critical-chain | Critical path through boot sequence |
| systemd-analyze plot > boot.svg | Generate SVG boot timeline chart |
| systemd-analyze verify myapp.service | Validate a unit file for errors |