If you've ever typed systemctl status on a fresh server and wondered why it isn't service status or some old init script, you've bumped into one of the more debated shifts in Linux history. Init and systemd both do the same basic job: they get your machine from "just powered on" to "actually usable." How they go about it, though, is almost completely different, and that difference shapes how you troubleshoot boot problems, manage services, and think about the Linux boot process in general.
This article walks through what an init system actually is, how the older SysV init worked, what systemd changed, and how you can check and manage either one on a live server.
What is an init system, exactly?
Every Linux (and Unix) system needs a first process. When the kernel finishes loading and mounting the root filesystem, it hands off control to a single program, and that program becomes PID 1. Whatever that program is, whether it's a decades-old shell script interpreter or a modern service manager, it's called the init system.
PID 1 has a few jobs that never change no matter which init system you're running. It starts all the other system services and daemons in the right order. It becomes the parent of any process whose original parent has already exited, which means it's responsible for "reaping" those orphaned processes so they don't pile up as zombies. And it stays alive for the entire life of the system, since if PID 1 dies, the kernel panics.
Historically, "init" referred to a specific program: System V init, often shortened to SysV init. These days, "init system" is more of a general term, and systemd is simply the init system most major distributions ship with by default.
SysV init: the traditional approach
SysV init traces back to Unix System V and was, for a long time, the standard init system across most Linux distributions, including older versions of Debian, Ubuntu, Red Hat, and CentOS. It works around the idea of runlevels, numbered states (0 through 6) that each correspond to a particular system configuration. Runlevel 0 means shutdown, runlevel 1 is single-user rescue mode, runlevel 3 is a full multi-user system without a graphical interface, runlevel 5 adds a GUI, and runlevel 6 triggers a reboot.
When the system enters a runlevel, init looks in the matching /etc/rc.d (or /etc/rcX.d) directory for a set of symbolic links pointing to shell scripts, then runs them in numeric order. Each of those scripts is a genuine shell script, often bash, that starts or stops a particular service by defining its own start, stop, and status logic. If you've wondered what other types of shells could be running a script like this, this is a good example of bash doing real system work, not just interactive typing.
That flexibility came at a cost. SysV init starts services sequentially: script two doesn't run until script one finishes, whether or not they depend on each other. On a machine with a dozen or more services, that adds up to a slow boot. Worse, init had no real concept of dependencies between services. If a database needed the network up first, that ordering had to be baked into filenames and symlink numbers by hand, and different distributions handled the details slightly differently, which made scripts hard to port.
systemd: a modern init system and service manager
systemd was introduced by Lennart Poettering and Kay Sievers around 2010, and Fedora was the first major distribution to adopt it, in 2011. Today it's the default init system on Ubuntu, Debian, Fedora, RHEL, and their downstream relatives like Rocky Linux and AlmaLinux. It's still PID 1 and still responsible for reaping orphans, so it satisfies the same basic definition of an init system, but the mechanics underneath are quite different.
Instead of shell scripts, systemd uses unit files: plain-text configuration files that declare what a service needs rather than scripting out how to start it. A typical .service unit might just list the executable to run, which user to run it as, and which other units it depends on. systemd reads those dependencies and builds a graph, then starts services in parallel wherever it can, only serializing the ones that genuinely need to wait on each other. That's the single biggest reason systemd boots faster than SysV init on most hardware.
Runlevels are replaced by targets, which are really just units that group other units together. multi-user.target roughly corresponds to the old runlevel 3, and graphical.target corresponds to runlevel 5, but targets are more flexible since a system can activate several at once and depend on each other. systemd also bundles functionality that used to live in separate tools: journald for centralized logging, socket and timer activation so services start only when needed, and tight integration with Linux namespaces and cgroups for tracking each service's processes. That cgroup integration is why systemd can reliably kill every process belonging to a service, even ones that fork children the original script never knew about.
For backward compatibility, systemd can still parse old SysV init scripts as a fallback, and distributions maintain service and other wrapper commands so muscle memory from the SysV era mostly still works. The official systemd documentation on freedesktop.org covers the full unit file syntax and manager behavior in detail if you want to go deeper than this article does.
Where systemd draws criticism
Not everyone was thrilled about the switch, and it's worth mentioning briefly for balance. Critics have pointed out that systemd concentrates a lot of functionality, logging, device management, network configuration helpers, and more, into one project, which cuts against the traditional Unix philosophy of small tools that each do one thing. Some sysadmins also found early versions harder to debug than a plain shell script, since understanding a boot failure now sometimes means reading unit dependency graphs instead of just reading a script top to bottom.
That pushback is part of why alternatives like OpenRC and runit still exist and see real use, particularly on distributions such as Alpine Linux, Gentoo, and Void Linux. Both aim for simpler, more transparent init systems with less built-in scope than systemd, at the cost of some of the parallelization and unit-management features systemd offers out of the box. If you're running containers or minimal images, there's a decent chance you've already encountered one of these without realizing it.
How to check which init system you're running
If you're not sure what a given server is using, there are a couple of quick ways to check. The most reliable is to look at what process 1 actually is:
ps -p 1
If the output shows systemd in the CMD column, you're running systemd. On an older SysV-based system, you'd typically see init instead. You can also check directly:
readlink /proc/1/exe
This resolves the actual binary backing PID 1, which will point to something like /usr/lib/systemd/systemd on a modern distribution. Another option, if the systemctl binary exists on the box at all, is simply running systemctl with no arguments; if it returns a live list of units, systemd is managing the system, since the command won't function meaningfully otherwise.
Basic systemctl commands worth knowing
Once you know you're on a systemd-based system, a handful of systemctl commands cover the vast majority of day-to-day service management. Checking a service's current state is the one you'll reach for most:
systemctl status nginx
Starting and stopping a service is straightforward too:
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
Note that starting or stopping a service only affects its current running state; it won't survive a reboot on its own. To make a service come up automatically at boot, you enable it:
systemctl enable nginx
And to stop it from launching at boot without touching whether it's currently running, disable it:
systemctl disable nginx
For a quick sanity check across the whole system, systemctl list-units --type=service shows every loaded service unit and its state, and journalctl -u nginx pulls that service's logs straight out of the systemd journal, which is often faster than hunting through separate log files under /var/log.
Conclusion
Init and systemd both solve the same problem of turning a booting kernel into a working system, but they go about it in very different ways: one relies on sequential shell scripts and numbered runlevels, the other on declarative unit files, dependency graphs, and parallel startup. Knowing which one you're running, and how to check it, makes troubleshooting a stuck boot or a misbehaving service a lot less confusing.
Thanks for reading! If you're looking for reliable infrastructure, xTom provides enterprise-grade dedicated servers and colocation services, while V.PS offers scalable, production-ready NVMe-powered VPS hosting perfect for any workload. You can also explore IP transit, shared hosting, and general IT services for whatever your infrastructure needs.
Ready to discuss your infrastructure needs? Contact our team to explore the right solution for your projects.
Frequently asked questions about init and systemd
Is systemd the same thing as init?
Not exactly. "Init" is a general term for whichever program becomes PID 1 and manages system startup; systemd is one specific implementation of that role, alongside older ones like SysV init and alternatives like OpenRC. On most modern distributions, systemd is the init system, so in casual conversation people often use the terms interchangeably.
Why did distributions move away from SysV init?
Mainly for speed and consistency. SysV init's sequential, shell-script-based startup couldn't take advantage of dependency information, so boots were slower than they needed to be, and every distribution handled runlevel scripts a bit differently. systemd's unit files and parallelized startup addressed both problems, which is why Fedora, Debian, Ubuntu, and RHEL all eventually adopted it as the default.
Does every Linux distribution use systemd now?
Most of the major ones do, including Ubuntu, Debian, Fedora, RHEL, and their derivatives like Rocky Linux and AlmaLinux. It's not universal, though; distributions like Alpine Linux, Gentoo, and Void Linux use OpenRC or runit instead, often because they prioritize a smaller footprint or a simpler init model.
Can I still use SysV-style init scripts on a systemd system?
Generally, yes. systemd includes compatibility shims that can parse traditional SysV init scripts, and most distributions keep the service command working as a wrapper around systemctl. That said, native unit files are the preferred approach going forward, since they integrate properly with dependency resolution, logging, and cgroup tracking.
What happens if PID 1 crashes?
The kernel treats the loss of PID 1 as a fatal, unrecoverable event and panics rather than trying to continue, which is exactly why the init system, whichever one it is, needs to stay running and stable for as long as the machine is up.
