systemd vs SysV init
PID 1 is the first userspace process and the ancestor of everything else on your system. For decades it was a simple program called init. Today most Linux distributions use systemd, which works very differently. Here's why it changed and how it works.
SysV init — Sequential Shell Scripts
Traditional SysV init worked simply: it read /etc/inittab, determined the runlevel, and executed shell scripts in /etc/rcX.d/ one by one.
# SysV startup sequence (simplified)
/etc/rc0.d/ ← runlevel 0 (halt) scripts
/etc/rc1.d/ ← runlevel 1 (single user) scripts
/etc/rc5.d/ ← runlevel 5 (graphical) scripts
# Scripts named: S##name (start) or K##name (kill)
# Sorted and run in order:
S01networking
S10syslog
S20mysql
S30apache2 ← all run sequentially, one after another
Problems with SysV init:
- Sequential = slow. Each service waits for the previous to finish.
- Shell scripts are fragile and hard to get right.
- No standard way to check service status, restart on failure, or limit resources.
- Logs scattered across /var/log/ in different formats.
systemd — Parallel Dependency Graph
What makes systemd fundamentally different?
systemd starts services in parallel. It builds a dependency graph of all units and starts as many as possible simultaneously. Instead of "start A then B then C," it's "start A, B, and C in parallel unless B requires A."
Other key systemd features:
- Socket activation: systemd creates network sockets on behalf of services, activating them only when a connection arrives. Faster boot, lazy start.
- cgroup integration: Every service gets its own cgroup — clean process accounting, no orphaned processes.
- Declarative unit files: Replace shell scripts with structured configuration.
- Unified logging: journald collects all logs in one searchable binary format.
- Automatic restarts:
Restart=on-failurein unit file.
Side-by-Side Comparison
| SysV init | systemd | |
|---|---|---|
| Startup model | Sequential | Parallel dependency graph |
| Config format | Shell scripts | Declarative .ini-style unit files |
| Service status | Fragile (exit codes) | Structured (systemctl status) |
| Logging | Scattered text files | Unified journald binary log |
| Resource limits | Manual (ulimit in scripts) | Built-in via cgroups |
| Boot speed | Slow (serial) | Fast (parallel) |
Essential systemctl Commands
# Service lifecycle
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl reload nginx # reload config without restart
# Enable/disable at boot
systemctl enable nginx # start on boot
systemctl disable nginx
# Status and inspection
systemctl status nginx # detailed status + recent logs
systemctl is-active nginx # active or inactive
systemctl list-units --type=service --state=running
# System targets
systemctl isolate multi-user.target # switch target
systemctl get-default # show default target
systemctl set-default graphical.target