systemd: why do some Linux distributions go out of their way to avoid it?

· 26 min read · #linux · #unix · #sysadmin · #debian · #operating-systems · #history

Contents

I was reading about antiX when something caught my eye. It's a lightweight distribution, happy on old machines, based on Debian, and it deliberately stays away from systemd. With antiX 26, released on March 21, 2026, it went further than I expected: you get five init systems to pick from, with runit as the default, plus SysVinit, dinit, s6-rc and s6-66. A bug-fix release, antiX 26.1, came out on September 29 with the same lineup.

My first guess was that the reason had to be simple. Maybe systemd is too heavy, or it doesn't like old hardware, or the antiX folks are just traditionalists. None of those explains much by itself.

What I found was a much better discussion. The systemd debate mixes operating system design, process management, cgroups, logging, security, portability, the Unix philosophy and, of course, culture. There's also a lot of historical noise in it: good technical criticism, criticism that stopped being true years ago, exaggerations, and slogans that people have been repeating for more than a decade.

To understand why anyone would choose not to use systemd, it helps to start with the problem it was trying to solve.

Before systemd #

For a long time, booting a Unix or Linux system meant some version of the traditional init model.

When the kernel finishes its part of the boot, it starts the first process in user space. That process gets PID 1. Historically, programs like SysVinit took that role, and PID 1 then coordinated the trip from an almost empty system to something you can use.

In the SysV world, most of that work lived in scripts under /etc/init.d/ and in the idea of runlevels. Each service had a script that understood actions like these:

/etc/init.d/ssh start
/etc/init.d/ssh stop
/etc/init.d/ssh restart

Distributions then created links and conventions to decide what started in each runlevel.

This model has a real virtue: you can read it. A shell script is a text file. If something looks odd, you open it, follow the commands and often run the same steps by hand.

Each script being simple doesn't make the whole system simple, though.

On a machine with dozens or hundreds of services, the hard questions show up fast. Does the database need to start before the application? Does the application need the network to be really up, or only the interface to be configured? What happens when a daemon calls fork() and creates children? Who restarts it when it dies? How do you know the process holding the PID written in a file is still the original one? How do you start things in parallel without races, and how do you describe dependencies without turning shell scripts into a web of conventions that change from one distribution to the next?

During the 2000s there were several attempts to modernize this. One of the best known was Upstart, from Canonical, which replaced part of the sequential logic with an event-driven model. Ubuntu used it for years before moving to systemd.

So when systemd showed up in 2010, it wasn't solving an invented problem. There was room for a service manager with better supervision, explicit dependencies and a more precise idea of what each process was doing.

A terminal window running Version 7 Unix: a directory listing with files dated June 1979, then cat /etc/rc showing a short boot script that sets PATH, prints a Western Electric restricted rights notice, mounts /usr, clears temporary files and starts update and cron

The /etc/rc of Version 7 Unix, from 1979. The whole boot story fit on one screen back then.

What systemd actually is #

Calling systemd "an init" is fine for a quick chat, and too little to understand the fight.

The systemd binary, running as PID 1, is a system and service manager. It starts and tracks services, builds a dependency graph, and manages states, sockets, mounts, timers, slices, scopes and other kinds of units.

But the name also covers a bigger project made of many programs and daemons. Depending on how a distribution is configured, these include (or have included):

systemd-journald
systemd-logind
systemd-networkd
systemd-resolved
systemd-timesyncd
systemd-udevd
systemd-homed
systemd-machined
systemd-boot

This matters because a common complaint says that "everything runs inside PID 1", and it doesn't. PID 1 is one process. systemd-journald is another, systemd-resolved is another, systemd-logind is another. They belong to the same project and are tightly integrated, but they aren't one big blob running in the same process.

It also explains why "systemd is monolithic" causes so much confusion. If monolithic means a single giant binary doing everything, the description is wrong. If the word is aimed at the broad scope of the project and how tightly its parts depend on each other, then there's a real architectural discussion to have.

PID 1 is a special place #

Minimalists don't worry about the size of PID 1 out of nostalgia. There's a technical reason.

On Unix and Linux, PID 1 has jobs ordinary processes don't. It adopts orphaned processes and has to reap terminated children correctly. The kernel also treats signals sent to PID 1 differently.

If PID 1 crashes for good, the machine doesn't carry on as if a text editor had closed. The system has lost its first user-space process, and the kernel panics.

That's why one school of thought wants something tiny as PID 1, with supervision, logging, networking and everything else moved into separate components.

The argument is reasonable. So is the reply: a modern PID 1 needs to know a lot about how services relate to each other to manage them properly, and pushing that complexity into dozens of external scripts doesn't make it go away.

For me the useful question isn't how many lines of code the project has. It's where the complexity lives, how it's contained, and how failures spread.

Why Fedora adopted it so early #

Fedora is the distribution that turned systemd from a new project into something seriously tested on Linux desktops. Its historical feature page for Fedora 15 said plainly that the goal was to replace SysVinit and Upstart.

Several ideas that became central were already there: aggressive parallel startup, socket and D-Bus activation, starting things on demand, tracking processes with cgroups, transactional dependencies, mounts and automounts treated as units, and .service files instead of long shell scripts.

Fedora 15, released in 2011, shipped systemd as the default.

Boot speed was part of the pitch at the time, but it wasn't the only reason. The design aimed at managing services better, not only at shaving a few seconds off startup.

That's still true in 2026. On modern hardware, boot is usually quick enough that nobody picks an init system over two or three seconds. Supervision, isolation, observability and cgroups are the stronger arguments.

Why Debian adopted it #

Debian's decision carried a lot of weight, because Debian is the base of a huge family of distributions.

In February 2014, after months of argument, the Debian Technical Committee decided that systemd would be the default init system for Jessie on Linux.

The vote also showed that the question was never just "which one boots faster". People were explicitly worried about coupling. Later in 2014 the project held a general resolution on whether packages could require a specific init system. The concern was that unrelated software could start depending on one implementation and make switching impractical. That resolution ended with the option "General Resolution is not required", so no rule was added.

The topic came back in 2019, in another general resolution, and the winning option was "Systemd but we support exploring alternatives". In practice, systemd is the focus and other init systems are welcome as long as people do the work.

That coupling worry is exactly what explains most of the work done by Devuan and antiX today.

Ubuntu, which had been using Upstart, followed the Debian ecosystem and switched to systemd in 2015.

From then on the center of gravity moved. Fedora, Debian, Ubuntu, Arch, SUSE and the other big distributions converged, and for software developers, shipping a systemd unit solved the problem for a huge share of Linux users.

That standardization is also what bothers the critics: the more software assumes systemd, the more expensive it gets to live outside it.

What is a unit? #

One of the best things in systemd is the idea of describing resources as declarative units.

A simple service unit can look like this:

[Unit]
Description=Example service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/example
Restart=on-failure

[Install]
WantedBy=multi-user.target

Instead of writing start() and stop() functions by hand, juggling PID files and repeating the same daemonization logic in every script, you declare the main process and how it should run.

systemd has many unit types. The most common are .service, .socket, .timer, .mount, .automount, .path, .target, .slice, .scope and .device.

A .service describes a service. A .socket allows socket activation. A .timer schedules runs. A .mount represents a mount point. A .target groups units and often works as a synchronization point, a bit like the old runlevels, though much more flexible.

Dependency and ordering are different things #

This looks like a small detail, and it's one of the smartest decisions in the model. Consider:

Requires=postgresql.service
After=postgresql.service

Requires= says one unit depends on another. After= only says which one goes first.

A unit can need to start after another without pulling the other one in. And it can want a dependency without that dependency deciding the whole order. In classic SysV, these two ideas usually got mixed together in the order of the scripts. systemd keeps them separate.

Wants= is a weaker dependency than Requires=, and Before= is the mirror image of After=. Together they form a graph the service manager can check before running a transaction.

Starting a daemon and managing it are different jobs #

A big difference between the old and new models is supervision.

Starting a process is easy:

/usr/local/bin/example &

Looking after it is another story. Who notices that it died? Who restarts it? Who records its state? Who knows which child processes belong to it, and who kills all of them at shutdown?

With systemd, these two lines already describe a basic supervision policy:

[Service]
ExecStart=/usr/local/bin/example
Restart=on-failure

This isn't unique to systemd. runit and s6 have excellent supervision, and that's exactly why they're much more interesting alternatives than going back to plain SysVinit. What systemd did well was combine supervision with the rest of how a modern Linux system is managed.

Cgroups changed process management #

This is one of the most important parts of the story.

Picture a service made of a main daemon that spawns two workers and a helper. In the old model, reliably finding every process that belongs to that service gets complicated. A PID file helps with the main process, but it says nothing solid about the whole tree.

Linux cgroups solve this at a different layer. systemd puts each service in its own cgroup, so the service manager stops asking "what's the daemon's PID?" and starts managing the group of processes that belongs to the unit.

That helps with shutdown, restarts, accounting, memory and CPU limits, knowing which processes are part of a service, isolation, and handing parts of the tree over to containers.

With cgroup v2, systemd organizes services, sessions, scopes and slices into a hierarchy, and its documentation describes system.slice, user.slice and machine.slice as standard parts of that tree. The old cgroup v1 is gone for good: systemd 258 removed support for the legacy and hybrid hierarchies, so cgroup v2 is always mounted at boot.

This is a place where systemd is deeply tied to Linux, on purpose. Fedora's earliest documents already said the project didn't plan to be portable to other Unix systems, because the idea was to use Linux kernel features aggressively.

If you think "Linux first", that's a plus. If you value software that moves between Linux, FreeBSD, OpenBSD and friends, it's the opposite.

Socket activation #

Socket activation gets mentioned a lot and explained very little.

Normally we think of it in this order: the daemon starts, the daemon opens its port or socket, and clients can connect.

With socket activation, the service manager opens the socket first. A client connects, the service is started, and the socket is handed over to it.

That lets you start services on demand and, in some cases, start dependencies in parallel: a client can begin talking to a socket while the process that will answer it is still starting up.

The software has to support this model, and not every daemon gains from it. Used in the right place, it's a very handy tool. s6 also has mechanisms related to socket activation, so this isn't something only systemd can do.

Timers and cron #

cron is still great. A line like this is short, everyone recognizes it, and it's perfect for lots of jobs:

0 3 * * * /usr/local/bin/backup

systemd timers solve the same kind of problem inside the service manager. A .timer triggers a .service, so the job gets the same model for logs, dependencies, user, sandboxing, resource limits and status. Timers also have nice extras, like randomized delays, monotonic timers, and catching up on runs that should have happened while the machine was off, depending on how you configure them.

The choice doesn't have to be religious. If I have half a dozen simple scripts on a server, cron may be clearer. If the job is already a service unit and needs the same security and logging rules, a timer usually fits better.

journald and the log war #

Probably no part of systemd annoyed old-school admins as much as journald.

The classic Unix model is comfortable: text files like /var/log/syslog, /var/log/messages and /var/log/auth.log, read with grep, awk, sed, tail and less. Text is transparent, easy to copy, easy to recover, and every tool from the last few decades understands it.

journald chose its own structured format. You read it with journalctl and can filter by unit:

journalctl -u nginx

You can also filter by boot, PID, UID, priority, time window and plenty of other metadata.

The gain is real. A log entry stops being just a line of text and carries structured context, which makes a lot of operational questions very easy to answer.

The criticism is real too. You now depend on tools that understand the journal, and cat isn't enough to look at the raw files.

Saying "binary logs are bad" is shallow, though. Databases and structured formats aren't useless just because they aren't plain text. The real question is whether indexing and metadata are worth the cost of special tools and a more specialized recovery process.

Another exaggeration is that journald rules out syslog. It doesn't. systemd can live alongside traditional syslog daemons, and distributions forward messages however their policy says.

My reading is that the strongest criticism isn't "binary means bad". It's that you lose the ability to swap things out and handle them with generic Unix tools, and that's a much more interesting architectural point.

Sandboxing without putting everything in a container #

One systemd feature admins tend to underestimate is what systemd.exec lets you do. A service unit can carry restrictions like these:

[Service]
ExecStart=/usr/local/bin/example
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
MemoryMax=512M
CPUQuota=50%
CapabilityBoundingSet=

They come from different families. NoNewPrivileges=yes stops the process and its children from gaining privileges through things like setuid binaries. ProtectSystem= and ProtectHome= change what parts of the filesystem the service can see and write. PrivateTmp=yes gives it its own temporary directories, and PrivateDevices=yes limits access to devices. RestrictAddressFamilies= limits which kinds of sockets it can open. MemoryMax= and CPUQuota= use resource controls. CapabilityBoundingSet= trims the Linux capabilities available, and SystemCallFilter= can restrict whole sets of system calls.

None of this turns an insecure program into a secure one by magic. Hardening means understanding the service, and a bad rule can break the application or give you a false sense of safety.

Still, for lots of small daemons, these options give you useful limits without building a Docker container just to get basic isolation. You can even get a first assessment with:

systemd-analyze security name.service

and use the result as a starting point for a review.

So why do people say systemd breaks the Unix philosophy? #

The line everyone quotes is "Do one thing and do it well."

It's a real tradition, but it isn't a constitutional article of Unix. The idea is to prefer small programs, simple interfaces, composition and replaceable parts, talking to each other through predictable mechanisms, very often text and pipes.

systemd was born from a different priority: managing the system as one coherent whole. It's made of many separate components, but they share conventions, libraries, APIs, unit formats, D-Bus and a common view of the machine.

Its defenders say this removes duplication, fixes cases that independent scripts handled badly, and gives everyone a consistent platform. Its critics say it creates a central layer with too much reach. Both are describing something real.

The conversation gets poor when each side draws a cartoon of the other. Not every critic wants to go back to Unix in 1975, and not every form of integration is automatically "anti-Unix".

When an init stops being just an init #

The project has grown a lot since 2010. Besides managing the system and its services, the systemd family now covers logging, logins and sessions, DNS, networking, time sync, devices, temporary files, mounts, containers, boot, users, credentials, home directories and more.

This is where the scope creep criticism gets stronger.

An admin might love systemd.service and not want systemd-resolved. They might use journald and prefer NetworkManager over networkd. On many distributions that's perfectly possible.

But the fact that components are optional doesn't settle the architectural question. Taken as a whole, the project has become one of the main infrastructure hubs of Linux user space. That brings integration gains, and it also concentrates a lot of decisions in one place.

A serious critique doesn't need a conspiracy theory about "taking over Linux". It's enough to notice that when one project is responsible for this much, its technical and social decisions hit everyone harder.

The real problem is the ecosystem around it #

At first the question looked like "systemd versus some other init".

Today it looks more like a whole stack: init, login and session management, udev, D-Bus, desktop environments, service units, cgroups, packaging, libraries and distribution policy.

That's what makes antiX and Devuan interesting. Replacing /sbin/init isn't enough. Desktop software may expect interfaces that logind provides. Packages may ship only systemd units. Upstream documentation may assume systemctl. Some integrations expect udev, cgroups or behavior defined by the systemd ecosystem.

Distributions without systemd have to decide how to fill those gaps, and two names come up a lot. elogind takes the login and session management out of systemd so it can run without systemd as PID 1. eudev started as a fork of udev for people who wanted less dependence on the systemd suite. Device management varies by distribution, and some use other tools, like mdev on Alpine.

That's the difference between "not installing systemd" and "keeping a modern distribution running without depending on the systemd ecosystem". The second one is ongoing work that never really ends.

KaOS is a good recent example of how blurry that line is. In 2026 it finished moving its init to dinit, with turnstile and seatd handling sessions and seats. Its own release notes say that doesn't make the system systemd-free: it still uses systemd's udev and tmpfiles, and elogind is there so polkit works.

antiX, the distro that started this #

The antiX 26 desktop with a dark wallpaper of glass boxes, the application menu open on Accessories, and a system monitor in the top right corner listing runit as the init system

The antiX 26 desktop. What you see changes with the window manager you pick.

antiX is a fun case in 2026 because it didn't just choose "the old init". antiX 26 is based on Debian 13 "Trixie" and ships runit as the default, with SysVinit, dinit, s6-rc and s6-66 as alternatives. That says a lot about what the project wants.

The focus is still lightweight systems, old machines and user control, but the current strategy admits that there are modern alternatives to systemd, and SysVinit isn't the only one. runit does real supervision. dinit has dependencies and parallel startup. s6 is built around a supervision tree that's very hard to kill.

So when someone sums up antiX as "they skip systemd because it's heavy", they miss the best part. antiX is choosing a different way of putting a system together.

Devuan #

Devuan was born straight out of Debian's decision to adopt systemd. Its current stable release, Devuan 6 "Excalibur", came out on November 2, 2025, and is based on Debian 13.

Devuan doesn't pretend the modern ecosystem isn't there. It does the work so you can have a Debian-like system without systemd as PID 1, and its migration guide from Debian Trixie to Excalibur shows that work almost like a lesson. Along the way you install packages like these:

sysvinit-core
eudev
elogind

In other words, removing systemd means replacing jobs that a standard Debian install already has wired together.

Devuan uses SysVinit by default and also supports alternatives such as OpenRC and runit. If you want Debian without systemd, Devuan makes more sense than ripping systemd out of a current Debian by hand, because the distribution takes responsibility for keeping that choice working.

Void Linux and runit #

Void is probably one of the best answers to the idea that "without systemd you're stuck with old technology". Void uses runit.

runit is small, portable and focused on supervision. Each service is a directory, usually with a run script that starts the daemon in the foreground. On Void you manage them like this:

sv up nginx
sv down nginx
sv restart nginx
sv status nginx

Enabling a service means linking its directory into the supervised directory.

The runit documentation makes an important point: the supervisor knows the process it started directly, which avoids a lot of the old fragility of PID files and double forking.

What I like about this model is that supervision is treated as the main problem, and the supervisor doesn't grow into a platform for DNS, networking, logins and the bootloader. That separation is exactly what draws people to it. The price is that everything else has to be handled by other tools and by the distribution's integration work.

Alpine Linux and OpenRC #

Alpine uses OpenRC as its default init and service manager.

OpenRC stays close to the script tradition, but adds explicit dependency handling and its own tools:

rc-service nginx start
rc-service nginx stop
rc-update add nginx
rc-status

Alpine is good evidence because it's everywhere in containers and minimal servers. Running without systemd doesn't stop a Linux system from being modern, supporting cgroup v2 or running current workloads.

It also shows that there's a cost. Init scripts for each system have to be packaged, and Alpine often ships them as separate -openrc packages. Other alternatives may not have ready-made scripts at all.

Artix #

Artix is more or less "Arch without systemd". It offers variants with OpenRC, runit, s6 and dinit, keeping the rolling-release Arch experience while letting you pick the init.

It's a good lab if you want to compare models without giving up a modern desktop. You also have to accept that a lot of Arch documentation assumes systemd, so at some point you'll be translating systemctl enable --now x into whatever your variant uses.

Gentoo #

Gentoo goes with what fits its culture: choice. OpenRC is the historical, native option, and systemd is fully supported too.

That coexistence shows that both designs can be first-class when a distribution decides to maintain both. It's also a reminder that "without systemd" doesn't have to mean "anti-systemd".

The alternatives #

SysVinit #

SysVinit is historically important and still works. Its strengths are predictability, familiarity, and a design that keeps most of the work visible in scripts.

On its own, though, it doesn't give a complete modern answer for supervision, process groups and dependencies, so using it today usually means pairing it with other tools.

runit #

runit is small and elegant. It has simple supervision, a service model that's easy to understand, automatic restarts, a small codebase, and it runs on several Unix-like systems.

It shines when you want each service to be a supervised foreground process and you'd rather build the rest of the system from independent tools.

OpenRC #

OpenRC is the natural next step for people who like the traditional model. It gives you dependencies, runlevels and consistent management without taking on systemd's scope.

It's especially nice on Gentoo and Alpine, where the distribution already does the integration work.

s6 #

s6 may be the most technically impressive of the minimalist options. It starts from a small, very sturdy supervision tree, and the wider s6 family adds service management and init pieces while keeping the idea of small tools you combine.

The catch is ergonomics. For many people the learning curve is steeper than runit's or systemd's. Projects like s6-frontend aim to make it friendlier, but it still rewards people who want to understand the model in depth.

dinit #

dinit tries to sit in an interesting middle ground. It's compact, and it still has dependencies, parallel startup, controlled restarts and proper service management.

It got a lot more visible in 2026: antiX 26 offers it as an option, and KaOS switched its init to it. dinit is proof that people are still doing practical work on init and service managers. The discussion didn't end in 2015.

Things people say about systemd that aren't quite true #

"systemd is one giant binary" #

No. The project is big, but it's made of many separate programs and daemons. The fair criticism is about scope and integration, not about everything being compiled into one process.

"Everything runs inside PID 1" #

No. PID 1 runs the system and service manager. journald, logind, resolved, networkd and the rest are separate processes when they're in use.

"If the journal gets corrupted, you lose all your logs" #

That's an exaggeration. Corruption is a fair worry for any structured storage, but journald has its own tools and safeguards, and a traditional syslog can run next to it. The stronger criticism is the dependence on specific tools.

"systemd replaced all of Unix" #

No. It took over a lot of infrastructure work in modern Linux, but it still lives alongside the shell, cron, syslog, NetworkManager, DNS servers, containers and dozens of other tools whenever the distribution sets things up that way.

"systemd is always slower" #

There's no serious basis for that. Boot time depends on hardware, services, distribution and configuration, and the design was built for parallel startup and on-demand activation.

It's also true that a minimal runit system may have fewer moving parts and boot very fast. A benchmark without context is worth very little.

"systemd only exists because Red Hat forced it on everyone" #

Red Hat had huge influence, since Fedora was the first big adopter and Lennart Poettering worked there. But Debian made its own decision after a long and heated debate, and Arch, SUSE, Ubuntu and others went through their own processes. Influence isn't the same thing as a central order.

"Modern Linux doesn't work without systemd" #

antiX, Devuan, Void, Alpine, Artix and Gentoo show the opposite every day. What's true is that keeping a modern Linux desktop running without systemd can take extra integration work.

"systemd is spyware" #

There's no technical basis for that as a description of the project.

"systemd is insecure by definition" #

No. More complexity means more room for bugs, and that's worth discussing. At the same time, systemd offers sandboxing, capabilities, namespaces and cgroups that can shrink what a service exposes. Security has to be judged by threats and configuration, not slogans.

"Anyone who dislikes systemd is just nostalgic" #

That's a cartoon. There are perfectly modern criticisms about coupling, portability, replaceability and how much responsibility sits in one project.

"The alternatives are always simpler" #

No. runit is simple as a concept, but a full desktop built around it may need several extra pieces, scripts and decisions. A simple component doesn't guarantee a simple system.

The criticisms that hold up #

Once the exaggerations are set aside, there's still plenty of serious material.

The scope is enormous #

There's no way around it. The project covers a large part of Linux user space, and that means more and more architectural decisions go through the same ecosystem.

Coupling keeps growing #

Even when a component is optional, other software may assume its interfaces. An alternative distribution has to follow upstream projects, maintain scripts, adjust dependencies and provide replacements.

Portability isn't a goal #

systemd is deliberately Linux-only. If your idea of Unix includes software that can be shared between Linux and the BSDs, that's a structural drawback, not a footnote.

Debugging can get abstract #

When everything works, systemctl status and journalctl are excellent. When a unit lands in a strange state because of a dependency, a generator, an override, a target or a cgroup interaction, you need to understand the systemd model. Declarative doesn't always mean simple.

Responsibility is concentrated #

A bug or a change in systemd can hit many distributions at the same time. That's the other side of standardization.

A good example from this year: systemd 260, released in March 2026, removed support for System V init scripts. The SysV generator, rc-local.service and the systemd-sysv-install hook are gone, and the release notes ask everyone to ship native unit files "now". Ubuntu, for instance, asked package maintainers to add systemd services for Ubuntu 26.10, because 26.04 LTS was the last release with the generator. One upstream decision, and every distribution that still carried old init.d scripts had homework.

The strengths that deserve respect too #

systemd manages services for their whole life, not only during boot. Being able to track every process in a unit and put limits on it is excellent on servers. For many services, a .service file is shorter and less ambiguous than a full init script.

The tools are consistent. These commands behave the same way on a huge number of distributions:

systemctl status nginx
journalctl -u nginx
systemctl list-dependencies nginx

You can apply isolation rules right in the service. Per-user services are very handy for desktop apps and long-running agents. Timers bring scheduling into the same supervision, logging and security model. And mass adoption produced a mountain of documentation, examples and know-how.

If you want cgroup v2, containers, resource management, sessions and services all working in one model, systemd is a very capable answer.

A slightly more hardened example #

Take the simple unit from before and add a few lines:

[Unit]
Description=Example service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/example
Restart=on-failure
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
MemoryMax=512M

[Install]
WantedBy=multi-user.target

Now the service manager isn't only starting /usr/local/bin/example. It's setting a restart policy, giving the process a narrower view of the filesystem and capping its memory. That's why "systemd is only about booting" stopped being true a long time ago.

Would I rip systemd out of a modern Debian? #

On an ordinary Debian server, no.

It's possible, but the trade isn't worth it. Debian tests its packages, documentation and integration with systemd as the default. Remove it and you become responsible for fixing every incompatibility that a distribution like Devuan already took on as its whole mission.

If I had a concrete reason to avoid systemd, I'd pick a distribution built for that. For a minimal server, Alpine or Void are great choices. For a Debian-like system without systemd, Devuan is much more sensible. For playing with different philosophies, antiX 26 has become a really fun lab. And for anyone who wants maximum control and has the time, Gentoo is still one of the most flexible options around.

Removing systemd from Debian just to prove it can be done usually turns a design preference into a pile of unnecessary chores.

What about servers? #

On servers, systemd is usually a practical win: cgroups, resource limits, restart policies, logs, hardening and the same admin commands everywhere.

On hosts running Docker or Podman, systemd on the host and the container runtime work at different levels. systemd can manage the runtime daemon and the cgroup tree, and inside small containers there's usually no need for a full service manager.

There's a subtlety here. Every container also has its own PID 1 inside its namespace, and people often use a tiny init there just to handle signals and reap children properly. Containers that really represent a whole system can run systemd as PID 1, as long as cgroups and permissions are set up for it.

So containers didn't make init systems irrelevant. They moved part of the discussion somewhere else.

What about the desktop? #

Most users never notice systemd directly. They notice that the session starts, the laptop suspends, devices show up, audio works, the network comes up and their apps launch.

Behind that are session management, udev, D-Bus, per-user services and the desktop's own integrations. That's why taking systemd off a desktop can be much more work than taking it off a simple server: the problem isn't starting nginx, it's keeping a whole graphical stack happy. Distributions without systemd handle it with elogind, eudev or mdev, scripts, and choices specific to each desktop. KaOS went as far as replacing Plasma with Niri on its dinit ISO, and its notes explain why Plasma isn't the easiest desktop to run without systemd.

Does the fight still make sense in 2026? #

Yes, but it's a different fight now.

In 2014 the question was whether systemd should win. In 2026 it already won as the default on the big Linux distributions, and the current release, systemd 262, came out in September. The interesting question now is how much of Linux user space should converge around it, and how much room is worth keeping for other designs.

That's a healthy question. antiX shipping five init systems is almost a practical answer to anyone who thinks the subject is closed. Void keeps showing that runit is enough to build a modern distribution. Alpine shows that OpenRC and cgroup v2 get along fine. Gentoo keeps two well-supported paths. dinit keeps evolving and won over KaOS. s6 keeps exploring a very modular take on supervision.

At the same time, systemd got better, more mature, and harder to wave away as "a bloated init". It solved real problems. Supervision beats hunting for PID files. Cgroups beat guessing process trees. Declarative units are great for packaging. Timers, sandboxing and user services are practical tools. On a modern Debian, Fedora, Arch or Ubuntu, there's very little operational reason to tear it out without a specific need.

The criticisms about scope, coupling, portability and replaceability are still valid, though.

After digging into all this, my position ended up much calmer than the history of the fight would suggest. I wouldn't remove systemd from a distribution whose whole ecosystem was built and tested around it. On Debian servers, for example, it gives me more advantages than problems.

I also wouldn't want a Linux world where the alternatives disappeared. antiX, Void, Alpine, Devuan, Artix and Gentoo keep different ideas about supervision, init, composition and portability alive, and some of those ideas may end up shaping the mainstream one day.

That's what I didn't get when I started reading about antiX. The question was never really why anyone hates systemd. It's how much integration we want to pile into one central layer of the system, and how much we're willing to pay to keep the parts replaceable. The answer depends on the system you're building, and it's a lot more interesting than "systemd is heavy".

Sources #

systemd:

Adoption history:

Distributions without systemd as the default:

Alternatives: