SysVinit

Also known as: System V init

On this page 7

SysVinit, short for System V init, is the traditional init system of Unix-like operating systems, in which the first user-space process reads /etc/inittab and starts or stops services by running shell scripts grouped into runlevels. In Linux system initialization, it was the standard way to bring a machine from kernel startup to a usable state for roughly two decades.

Most major distributions replaced SysVinit with systemd in the mid-2010s, but SysVinit remains relevant: Devuan and some embedded and minimal systems still use it, many legacy services ship init scripts in its format, and systemd keeps compatibility layers that read those scripts.

How SysVinit boots a system

After the boot loader, such as GRUB, loads the kernel and the initramfs, the kernel starts /sbin/init as process ID 1. SysVinit’s init then reads `/etc/inittab`, which defines the default runlevel, the system initialization script and the processes to keep running, such as login prompts on virtual consoles.

Init first runs a system initialization script that mounts file systems, checks disks and sets the hostname. It then enters the default runlevel by calling the `rc` script, which executes the scripts linked in that runlevel’s directory one after another in a fixed order. This sequential model is simple and predictable, but it makes boot time the sum of all script durations.

StageComponentWhat happens
Process 1 starts/sbin/initKernel hands control to init
Configuration read/etc/inittabDefault runlevel and respawn entries are loaded
System initializationDistribution sysinit scriptFile systems mounted, hostname and clock set
Runlevel entryrc with the runlevel numberKill scripts then start scripts run in order
Login servicesgetty entries in inittabConsoles offer login prompts, respawned on exit
Stages of a SysVinit boot

Runlevels and init scripts

A runlevel is a numbered system state that determines which services run. Each runlevel has a directory such as /etc/rc3.d containing symbolic links to scripts in /etc/init.d. Links starting with S are started and links starting with K are killed, and a two-digit number after the letter sets the order, so S20network runs before S80apache.

RunlevelUsual meaningNotes
0HaltSystem shuts down
1 or SSingle-user modeMaintenance with minimal services
2Multi-userOn Debian, the full default level
3Multi-user with networking, text modeTypical server default on Red Hat systems
4Unused or locally definedAvailable for custom configurations
5Multi-user with graphical loginDesktop default on many distributions
6RebootSystem restarts
Conventional runlevels

Each init script accepts standard arguments such as start, stop, restart and status. Administrators use tools such as service, chkconfig on Red Hat systems or update-rc.d on Debian systems to run scripts and manage links, and telinit or init followed by a number to switch runlevels at runtime.

SysVinit compared with modern init systems

The main criticisms of SysVinit concern serial startup, the lack of service supervision and the reliance on hand-written scripts. Its successors address these in different ways.

Init systemService definitionStartup modelSupervision
SysVinitShell scripts in /etc/init.dSequential by link orderOnly for inittab respawn entries
systemdDeclarative unit filesParallel, dependency-based, socket activationBuilt in, with cgroups tracking
OpenRCShell-based scripts with dependency headersDependency-based, optional parallelismOptional supervisor
UpstartEvent-based job filesEvent-drivenBuilt in, now discontinued
SysVinit and other init systems

With SysVinit, a crashed daemon stays down unless an external tool restarts it, and service state is inferred from PID files that can become stale. Systemd tracks every process of a service in a control group and replaces runlevels with systemd targets, mapping runlevel 3 to multi-user.target and runlevel 5 to graphical.target.

Working with SysVinit scripts today

On systemd distributions, scripts in /etc/init.d are still honored through the systemd-sysv-generator, which creates wrapper units at boot. Dependency information comes from LSB header comments such as Required-Start and Default-Start at the top of each script.

TaskSysVinitsystemd
Start a serviceservice nginx startsystemctl start nginx
Enable at boot on Red Hat systemschkconfig nginx onsystemctl enable nginx
Enable at boot on Debian systemsupdate-rc.d nginx defaultssystemctl enable nginx
Change system statetelinit 3systemctl isolate multi-user.target
Check the current staterunlevelsystemctl get-default
Equivalent commands across init systems

When migrating a legacy service, the recommended practice is to write a native unit file rather than rely on the generator, because a native unit gains supervision, resource limits and reliable logging through journalctl.

Strengths, limitations and pitfalls

SysVinit’s main strength is transparency: every step is a readable shell script, and debugging means reading code and adding echo statements. It has few dependencies, which suits small embedded systems.

  • Slow boot: scripts run one at a time, and a script waiting on a network timeout delays everything after it.
  • Stale PID files make status report a service as running when it has crashed, or block restarts.
  • Fragile ordering: two-digit sequence numbers do not express real dependencies and break when packages choose conflicting values.
  • Inconsistent scripts: each package author implements start and stop logic differently, so behavior varies.
  • Environment differences: scripts run with a minimal environment, so commands that work interactively can fail at boot.

In simple terms

When a computer starts, something has to switch on all the background programs it needs. SysVinit is an older, very simple way to do that.

It works like a checklist read from top to bottom. Each line starts one program, and the next line waits until the previous one is done. This makes it easy to understand. It is also slower than newer systems, which can start many programs at once and restart them if they crash.

A practical example

A manufacturing company operates an older Linux-based machine controller that still uses SysVinit. A vendor supplied a monitoring daemon with an init script installed as S99monitor in runlevel 3, the default runlevel defined in /etc/inittab.

After a power cut, the daemon fails to start because its script runs before a network share is mounted by a later-added S99mountshare link, and both share the same sequence number. The engineer renames the mount link to S50 so it runs earlier and adds a respawn entry in inittab for the critical process, giving it basic automatic restarts. The next outage test shows a clean boot in the correct order, and the team documents the change while planning a migration to a newer platform with native service supervision.