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-failure in unit file.

Side-by-Side Comparison

SysV initsystemd
Startup modelSequentialParallel dependency graph
Config formatShell scriptsDeclarative .ini-style unit files
Service statusFragile (exit codes)Structured (systemctl status)
LoggingScattered text filesUnified journald binary log
Resource limitsManual (ulimit in scripts)Built-in via cgroups
Boot speedSlow (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