systemctl is the primary command for managing systemd, the init system used by virtually all modern Linux distributions including Ubuntu, Fedora, AlmaLinux, and Debian. It controls services, targets, timers, sockets, and the entire boot process. Mastering systemctl is essential for any Linux administrator managing production servers.
This comprehensive guide covers every systemctl command you need, from basic service management to advanced unit file creation and troubleshooting.
Service Management Basics
# Start a service
sudo systemctl start nginx
# Stop a service
sudo systemctl stop nginx
# Restart a service (stop then start)
sudo systemctl restart nginx
# Reload configuration without stopping (zero downtime)
sudo systemctl reload nginx
# Reload if supported, otherwise restart
sudo systemctl reload-or-restart nginx
# Check service status (detailed)
systemctl status nginx
# Enable service to start automatically at boot
sudo systemctl enable nginx
# Disable service from starting at boot
sudo systemctl disable nginx
# Enable AND start in one command
sudo systemctl enable --now nginx
# Disable AND stop in one command
sudo systemctl disable --now nginx
Checking Service Status
# Detailed status with recent log entries
systemctl status nginx
# Quick checks (useful in scripts)
systemctl is-active nginx # Returns "active" or "inactive"
systemctl is-enabled nginx # Returns "enabled" or "disabled"
systemctl is-failed nginx # Returns "failed" or "active"
# List all loaded services
systemctl list-units --type=service
# List only running services
systemctl list-units --type=service --state=running
# List all enabled services
systemctl list-unit-files --type=service --state=enabled
# List ALL failed services (critical for troubleshooting)
systemctl --failed
# Show service dependencies
systemctl list-dependencies nginx
systemctl list-dependencies --reverse nginx # What depends ON nginx
Creating Custom Service Unit Files
# View an existing unit file
systemctl cat nginx.service
# Show the unit file path
systemctl show -p FragmentPath nginx.service
# Create a custom service
sudo nano /etc/systemd/system/myapp.service
Example: Node.js Application Service
[Unit]
Description=My Node.js Application
Documentation=https://docs.myapp.com
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node server.js
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/var/www/myapp/.env
# Security hardening options
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/www/myapp/data /var/www/myapp/logs
PrivateTmp=yes
ProtectKernelTunables=yes
[Install]
WantedBy=multi-user.target
Example: Python Flask Application
[Unit]
Description=Flask Web Application
After=network.target
[Service]
Type=simple
User=flask
WorkingDirectory=/var/www/flask-app
ExecStart=/var/www/flask-app/venv/bin/gunicorn -w 4 -b 0.0.0.0:8000 app:app
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
# After creating or editing unit files, ALWAYS reload daemon
sudo systemctl daemon-reload
# Then enable and start
sudo systemctl enable --now myapp.service
# Check status
systemctl status myapp.service
Editing and Overriding Unit Files
# Create a drop-in override (recommended way to customize)
sudo systemctl edit nginx.service
# This creates /etc/systemd/system/nginx.service.d/override.conf
# Example override: increase restart timeout
# [Service]
# RestartSec=10
# TimeoutStartSec=90
# Edit the FULL unit file (replaces the entire file)
sudo systemctl edit --full nginx.service
# Always reload after editing
sudo systemctl daemon-reload
Journalctl ā Reading Service Logs
# View ALL system logs
journalctl
# Logs for a specific service
journalctl -u nginx
# Today's logs only
journalctl -u nginx --since today
# Logs from a time range
journalctl -u nginx --since "2026-04-11 08:00" --until "2026-04-11 12:00"
# Last hour's logs
journalctl -u nginx --since "1 hour ago"
# Follow logs in real-time (like tail -f)
journalctl -u nginx -f
# Show only errors and above
journalctl -u nginx -p err
# Priority levels: emerg, alert, crit, err, warning, notice, info, debug
journalctl -p warning..err # Range of priorities
# Kernel messages only
journalctl -k
# Current boot only
journalctl -b
# Previous boot
journalctl -b -1
# List all recorded boots
journalctl --list-boots
# Output as JSON (useful for parsing)
journalctl -u nginx -o json-pretty
# Show only last 50 lines
journalctl -u nginx -n 50
# No pager (dump to stdout)
journalctl -u nginx --no-pager
# Check journal disk usage and clean up
journalctl --disk-usage
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=30d
Systemd Timers (Modern Cron Alternative)
# List all active timers
systemctl list-timers
systemctl list-timers --all
# Example: Create a daily backup timer
# Step 1: Create the service (/etc/systemd/system/backup.service)
# [Unit]
# Description=Daily Database Backup
#
# [Service]
# Type=oneshot
# ExecStart=/opt/scripts/backup.sh
# User=backup
# Step 2: Create the timer (/etc/systemd/system/backup.timer)
# [Unit]
# Description=Daily Backup Timer
#
# [Timer]
# OnCalendar=*-*-* 02:00:00
# Persistent=true
# RandomizedDelaySec=300
#
# [Install]
# WantedBy=timers.target
# Step 3: Enable the timer
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl status backup.timer
# Timer calendar expressions:
# OnCalendar=hourly - Every hour
# OnCalendar=daily - Every day at midnight
# OnCalendar=weekly - Every Monday at midnight
# OnCalendar=*-*-* 06:00:00 - Daily at 6 AM
# OnCalendar=Mon *-*-* 09:00:00 - Every Monday at 9 AM
System Power and Boot Management
# Reboot
sudo systemctl reboot
# Shutdown (power off)
sudo systemctl poweroff
# Suspend to RAM
sudo systemctl suspend
# Hibernate to disk
sudo systemctl hibernate
# Enter rescue mode (single user)
sudo systemctl rescue
# Get current default boot target
systemctl get-default
# Set default target (runlevel equivalent)
sudo systemctl set-default multi-user.target # No GUI (server)
sudo systemctl set-default graphical.target # With GUI (desktop)
# Switch targets without reboot
sudo systemctl isolate multi-user.target
Masking Services and Boot Analysis
# Mask a service (completely prevent starting, even manually)
sudo systemctl mask nginx
# Creates symlink to /dev/null
# Unmask
sudo systemctl unmask nginx
# Analyze boot performance
systemd-analyze # Total boot time
systemd-analyze blame # Slowest services ranked
systemd-analyze critical-chain # Critical path visualization
systemd-analyze plot > boot.svg # Generate boot timeline SVG
# Verify unit file syntax
sudo systemd-analyze verify /etc/systemd/system/myapp.service
Troubleshooting Failed Services
# Step 1: Check what's failed
systemctl --failed
# Step 2: Get detailed status
systemctl status myapp.service
# Step 3: Read the logs
journalctl -u myapp.service -b --no-pager
# Step 4: Check the unit file for errors
systemd-analyze verify /etc/systemd/system/myapp.service
# Step 5: Show all service properties
systemctl show myapp.service
# Step 6: Reset failed state after fixing
sudo systemctl reset-failed myapp.service
# Common causes of service failures:
# - ExecStart path doesn't exist or isn't executable
# - User/Group doesn't exist
# - WorkingDirectory doesn't exist
# - Port already in use by another service
# - Missing environment variables
# - Permission denied on files/directories
Recommended Reading
Deepen your Linux administration skills:
Download our systemctl Commands Cheat Sheet for a printable quick-reference with all 40+ commands.