← Back
🔧 Service Management
1

Control a Service

Start, stop, restart, or reload a running service, and check its live status.

bash — start / stop / restart / reload
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
# reload re-reads config WITHOUT dropping connections
sudo systemctl reload nginx
bash — status
sudo systemctl status nginx
● nginx.service - A high performance web server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Sun 2026-07-06 10:30:00 UTC; 2h ago
   Main PID: 812 (nginx)
      Tasks: 3 (limit: 4657)
2

Enable / Disable at Boot

enable creates the boot symlink; --now also starts/stops the service immediately.

bash
# Start automatically on boot
sudo systemctl enable nginx
sudo systemctl disable nginx

# Enable + start now (most common)
sudo systemctl enable --now nginx

# Disable + stop now
sudo systemctl disable --now nginx
3

Inspect State & Unit Files

Query whether a service is running or enabled, list units, and read the actual unit file.

bash — quick checks
# Is it currently running?
systemctl is-active nginx

# Is it set to start at boot?
systemctl is-enabled nginx
bash — list units
# All loaded service units
systemctl list-units --type=service

# All installed services that are enabled at boot
systemctl list-unit-files --type=service --state=enabled
bash — read unit definition
# Show the full unit file (and any drop-ins)
systemctl cat nginx

# Show a single resolved property
systemctl show nginx -p MainPID
â„šī¸
After editing any unit file, run sudo systemctl daemon-reload so systemd re-reads the on-disk definitions. Without it, systemd keeps using the cached, pre-edit version.
📝 Custom Service Unit
4

Create Your Own Service

Write a unit file under /etc/systemd/system/, reload systemd, then enable and start it in one command.

bash — write the unit file
sudo tee /etc/systemd/system/myapp.service <<'EOF'
[Unit]
Description=My Application Service
After=network.target

[Service]
Type=simple
User=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/run.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF
bash — activate it
# Reload systemd so it sees the new unit
sudo systemctl daemon-reload

# Enable at boot + start right now
sudo systemctl enable --now myapp
âš ī¸
Run sudo systemctl daemon-reload after every edit to a unit file. If you forget, restart will silently keep running the old definition.
⏰ Timers (cron alternative)
5

A .timer + .service Pair

A timer triggers a matching oneshot service. OnCalendar sets the schedule; Persistent=true runs a missed job on next boot.

bash — the oneshot service
sudo tee /etc/systemd/system/backup.service <<'EOF'
[Unit]
Description=Nightly backup job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
EOF
bash — the timer
sudo tee /etc/systemd/system/backup.timer <<'EOF'
[Unit]
Description=Run backup.service daily at 03:00

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF
bash — activate the timer
sudo systemctl daemon-reload

# Enable + start the TIMER (not the service)
sudo systemctl enable --now backup.timer
â„šī¸
The .timer and .service must share the same base name (backup). systemd pairs them automatically, so the [Timer] section needs no explicit Unit=.
6

List & Inspect Timers

See when each timer last ran and when it fires next.

bash — list all timers
systemctl list-timers --all
NEXT                        LEFT       LAST                        PASSED  UNIT           ACTIVATES
Mon 2026-07-07 03:00:00 UTC 14h left   Sun 2026-07-06 03:00:00 UTC 9h ago  backup.timer   backup.service
bash — status of one timer
systemctl status backup.timer
🔎 journalctl — Reading Logs
7

Per-Unit Logs

Filter the journal down to a single service, follow it live, or show the last N lines.

bash
# All logs for one unit
journalctl -u nginx

# Follow live (like tail -f)
journalctl -u nginx -f

# Last 100 lines, no pager
journalctl -u nginx -n 100 --no-pager
8

Time & Boot Filters

Scope logs by time window or by which boot they came from.

bash
# Time window (accepts natural language)
journalctl --since "2024-01-01" --until "1 hour ago"

# This boot only
journalctl -b

# The previous boot
journalctl -b -1

# List all recorded boots
journalctl --list-boots
9

Priority & Kernel

Filter by log priority, view kernel messages, or get the annotated recent view.

bash
# Errors (and worse) from this boot
journalctl -p err -b

# Kernel ring buffer messages
journalctl -k

# Recent entries + explanatory help text
journalctl -xe
10

Disk Usage & Vacuum

Check how much space the journal uses and trim old entries.

bash
# How big is the journal on disk?
journalctl --disk-usage

# Keep only the last 7 days
sudo journalctl --vacuum-time=7d

# Cap total journal size at 500 MB
sudo journalctl --vacuum-size=500M
🚑 Troubleshooting
11

Diagnose Failures & Boot Time

Find failed units, clear their failed state, and analyze what slows down boot.

bash — failed units
# List everything that failed to start
systemctl --failed

# Clear the "failed" flag so a unit can be retried cleanly
sudo systemctl reset-failed
bash — boot analysis
# Rank units by how long they took to initialize
systemd-analyze blame
bash — validate a unit file
# Check a unit for syntax errors / bad directives
systemd-analyze verify /etc/systemd/system/myapp.service
✅
Pair these with journalctl -u <unit> -n 50 --no-pager to read the exact error a failing unit logged on its last start attempt.