systemd is the init system used by virtually all major Linux distributions today — Ubuntu, Debian, RHEL, Fedora, Rocky Linux, and more. It manages the boot process, handles services, mounts filesystems, and manages logging. Understanding systemd is essential for any modern Linux sysadmin.
What Is systemd?
systemd is PID 1 — the first process the kernel starts. It then starts everything else in parallel, which makes modern Linux boot much faster than older init systems. It organizes system resources as units: services, sockets, timers, mounts, and more.
systemctl --version
ps -p 1 # Confirm PID 1 is systemd
Managing Services with systemctl
systemctl status nginx # Show service status, recent logs
systemctl start nginx # Start immediately
systemctl stop nginx # Stop immediately
systemctl restart nginx # Stop + start
systemctl reload nginx # Reload config (no downtime if supported)
systemctl enable nginx # Start at boot
systemctl disable nginx # Do not start at boot
systemctl enable --now nginx # Enable AND start immediately
systemctl is-active nginx # Prints "active" or "inactive" (exit code 0/1)
systemctl is-enabled nginx # Prints "enabled" or "disabled"
Listing Units
systemctl list-units # All active units
systemctl list-units --type=service # Services only
systemctl list-units --state=failed # Failed units
systemctl list-unit-files # All installed unit files
systemctl list-unit-files --type=service | grep enabled # Enabled services
Viewing Logs with journalctl
systemd captures all service output in the journal:
journalctl # All logs (newest at bottom)
journalctl -b # Logs from current boot only
journalctl -b -1 # Logs from previous boot
journalctl -u nginx # Logs for nginx service
journalctl -u nginx -n 50 # Last 50 lines for nginx
journalctl -u nginx -f # Follow (live tail)
journalctl --since "2026-04-01" # Logs since date
journalctl --since "1 hour ago" # Last hour
journalctl -p err # Only errors
journalctl -k # Kernel messages only
Writing a systemd Service Unit
Unit files live in /etc/systemd/system/. Here is a complete example for a Node.js application:
sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js Application
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/node /opt/myapp/server.js
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production PORT=3000
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload # Reload unit files after editing
sudo systemctl enable --now myapp # Enable and start
sudo systemctl status myapp # Verify
Unit File Directives Explained
- [Unit] — metadata and ordering.
After=means start after these units are up. - [Service] — the actual service definition.
Type=simple— process stays in foreground (most common).Restart=on-failure— auto-restart if the process exits with error.RestartSec=5— wait 5 seconds before restarting.- [Install] — defines when to enable.
multi-user.target= normal multi-user mode.
Timers (Replacing Cron)
systemd timers are a modern alternative to cron, with better logging and dependency handling:
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl enable --now backup.timer
systemctl list-timers # List all active timers
Analyzing Boot Performance
systemd-analyze # Total boot time
systemd-analyze blame # Time per unit
systemd-analyze critical-chain # Bottleneck chain
systemd-analyze plot > boot.svg # Visual boot chart
Target Units (Replacing Runlevels)
systemctl get-default # Default target (usually graphical or multi-user)
sudo systemctl set-default multi-user.target # Boot to text mode
sudo systemctl isolate rescue.target # Switch to rescue mode
Dependency Management
systemctl list-dependencies nginx # What nginx depends on
systemctl list-dependencies --reverse nginx # What depends on nginx
Summary
systemd is the backbone of modern Linux systems. Use systemctl to manage services, journalctl to read logs, and unit files to define your own services. Writing a clean service unit with Restart=on-failure and proper logging ensures your applications are resilient and debuggable in production.