< the skull

SYSTEMD: WHY DO SOME LINUX DISTRIBUTIONS GO OUT OF THEIR WAY TO AVOID IT?
=========================================================================
2026-09-01

I was reading about antiX when something caught my attention. The distribution
presents itself as lightweight, suitable even for older machines, based on
Debian and, at the same time, deliberately continues without systemd. In version
26, released in March 2026, antiX went even further: it began offering five init
options, with runit as the default, in addition to SysVinit, dinit, s6-rc and
s6-66.

The first reaction is to imagine that the explanation is simple. Maybe systemd
is heavy. Maybe it is incompatible with older machines. Maybe the antiX
developers are simply traditionalists. None of those answers, on its own,
explains much.

What I found is a far more interesting discussion. The debate around systemd
mixes operating system architecture, process management, cgroups, logging,
security, portability, Unix philosophy and, inevitably, culture. There is also
quite a bit of historical noise. There are very good technical criticisms,
outdated criticisms, exaggerations and a considerable number of slogans that
have been repeated for more than a decade.

The best way to understand why someone would choose not to use systemd is to
first understand what problem it tried to solve.

Before systemd
--------------

For a long time, talking about booting a Unix or Linux system meant talking
about some variant of the traditional `init` model.

After the kernel finishes its part of the boot process, it starts the first
process in user space. That process receives PID 1. Historically, `init`
implementations such as SysVinit took on that role. PID 1 then coordinates the
transition from an almost empty system to a usable environment.

In the SysV world, much of that work was organized around scripts in:

  /etc/init.d/

and around runlevels. Each service had a script capable of accepting actions
such as:

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

Distributions created links and conventions to define what should start at each
runlevel.

This model has a real virtue: it is easy to inspect. A shell script is just a
text file. If something looks strange, you open the file, follow the commands
and, in many cases, run the same steps manually.

But local simplicity does not mean simplicity of the system as a whole.

On a machine with dozens or hundreds of services, difficult questions arise.
Does the database need to start before the application? Does the application
really depend on the network being available, or only on the interface having
been configured? What happens when a daemon calls `fork()` and creates children?
How do you restart it if it dies? How do you know that the process using the PID
recorded in a file is still the original process? How do you parallelize boot
without creating races? How do you express dependencies without turning shell
scripts into a web of conventions specific to each distribution?

During the 2000s, several attempts appeared to modernize this. One of the best
known was Upstart, created by Canonical. It replaced part of the sequential
logic with an event-driven model. Ubuntu adopted it before later migrating to
systemd.

When systemd appeared in 2010, then, it was not solving an invented problem.
There was room for a service manager with better supervision, explicit
dependencies and more precise knowledge of process state.

Traditional Unix boot sequence

An `/etc/rc` from Unix Version 7, from 1979. The historical model was much
smaller than that of a modern Linux system.

What systemd really is
----------------------

Calling systemd simply an “init” is accurate enough for a quick conversation and
insufficient for understanding the controversy.

The `systemd` executable, when used as PID 1, works as a system and service
manager. It starts and tracks services, builds a dependency graph, manages
states, sockets, mounts, timers, slices, scopes and other types of units.

But the name systemd also identifies a larger project, made up of several
programs and daemons. Among them are or have been, depending on the
distribution's configuration:

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

This distinction matters because a common criticism says that “everything runs
inside PID 1.” It does not.

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
integrated with one another, but they are not a single mass running inside the
same process.

This also explains why the phrase “systemd is monolithic” tends to cause
confusion. If “monolithic” means “a single gigantic binary doing everything,”
the description is wrong. If the word is being used to criticize the broad scope
of the project and the degree of integration among its components, then there is
a legitimate architectural discussion there.

PID 1 is a special place
------------------------

Minimalists are not concerned about the size of PID 1 out of nostalgia. There is
a technical reason.

On Unix and Linux, PID 1 receives responsibilities that ordinary processes do
not have. Among other things, it takes part in handling orphaned processes and
must correctly perform the reaping of terminated child processes. The kernel
also treats signals sent to PID 1 in a special way.

If PID 1 fails irrecoverably, the machine does not simply continue running as if
a text editor had closed. The system loses its primordial user-space process.

That is why there is a school of thought that prefers something extremely small
as PID 1 and moves supervision, logging, networking and other functions into
independent components.

The argument is reasonable. So is the counterargument: a modern PID 1 needs to
know quite a lot about service topology in order to manage it correctly, and
pushing complexity into dozens of external scripts does not make the complexity
disappear.

The useful question is not “how many lines of code does the project have?”, but
where the complexity lives, how it is bounded and how failures propagate.

Why Fedora adopted systemd so early
-----------------------------------

Fedora was the distribution that turned systemd from a new project into a
seriously tested alternative on the Linux desktop. The historical feature page
for Fedora 15 explicitly described the goal of replacing SysVinit and Upstart.

It already contained several ideas that would become central:

  * aggressive parallelization;
  * socket and D-Bus activation;
  * on-demand startup;
  * process tracking with cgroups;
  * transactional dependencies;
  * mounts and automounts treated as units;
  * `.service` files instead of large shell scripts.

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

An interesting detail in the documentation from the time is that boot speed was
present, but it was not the only motivation. The architecture aimed to improve
management, not merely shave a few seconds off startup.

That distinction remains relevant in 2026. On modern machines, boot is often
fast enough that nobody chooses an init system over a difference of two or three
seconds. Supervision, isolation, observability and integration with cgroups are
more important arguments.

Why Debian adopted systemd
--------------------------

Debian's decision was decisive because Debian is the foundation of a huge
ecosystem.

In February 2014, after months of discussion, the Technical Committee decided
that systemd would be the default init system for Debian Jessie's Linux
architectures.

The vote matters for another reason: it shows that the discussion was not simply
about “which one boots faster?” There was explicit concern about coupling.

Still in 2014, the project discussed whether packages should be allowed to
require a specific init system. One proposal warned about the risk of the
ecosystem making it impractical to switch init systems if unrelated software
began depending on a particular implementation.

That is exactly the issue that today explains much of the work done by
distributions such as Devuan and antiX.

Ubuntu, which used Upstart, ultimately followed the Debian ecosystem and adopted
systemd as the default starting in 2015.

From that point on, the center of gravity shifted. Fedora, Debian, Ubuntu, Arch,
SUSE and other major distributions converged. For software developers,
documenting a systemd unit began to solve the problem for a huge share of Linux
users.

That standardization advantage also produces the side effect that bothers its
critics: the more software assumes systemd, the more expensive it becomes to
live outside it.

What is a unit?
---------------

One of systemd's best aspects is the idea of representing 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 manually writing `start()` and `stop()` functions, manipulating PID
files and repeating daemonization logic, you declare the main process and
execution properties.

systemd has several types of units. Among the most common:

  .service
  .socket
  .timer
  .mount
  .automount
  .path
  .target
  .slice
  .scope
  .device

`.service` describes services. `.socket` allows socket activation. `.timer`
schedules executions. `.mount` represents mounts. `.target` aggregates units
and, in many cases, works as a synchronization point conceptually similar to old
runlevels, although the model is more flexible.

Dependency is not the same thing as ordering
--------------------------------------------

This detail seems small, but it is one of the model's smartest decisions.

Consider:

  Requires=postgresql.service
  After=postgresql.service

`Requires=` expresses a dependency relationship.

`After=` expresses ordering.

A unit may need to start after another without necessarily causing the other one
to start. And it may want a dependency without, by itself, determining the
entire ordering.

In traditional SysV, these two ideas often ended up mixed together in script
sequencing. systemd makes them explicit.

`Wants=` expresses a weaker dependency than `Requires=`. `Before=` is the
inverse of an `After=` ordering relationship.

This produces a graph that the service manager can analyze before executing
transactions.

Supervision: starting a daemon is not the same as managing it
-------------------------------------------------------------

An essential difference between old and new models is the idea of supervision.

Starting a process is easy:

  /usr/local/bin/example &

Managing its lifecycle is another matter.

Who checks whether it died? Who restarts it? Who records its status? Who knows
which child processes belong to the service? Who terminates all of them during
shutdown?

With systemd:

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

already describes a basic supervision policy.

This is not exclusive to systemd. runit and s6 provide excellent supervision,
and that is precisely why they are far more interesting alternatives than simply
going back to pure SysVinit.

systemd's merit was combining supervision with the rest of the modern Linux
administration model.

Cgroups changed process management
----------------------------------

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

Imagine a service that creates this tree:

  main daemon
  ├── worker
  ├── worker
  └── helper

In the old model, reliably identifying every process that belongs to the service
can become complicated. PID files help with the main process, but they do not
robustly represent the entire tree.

Linux cgroups solve that problem at another layer.

systemd places services into cgroups. As a result, the service manager stops
thinking only in terms of “what is the daemon's PID?” and starts managing the
group of processes that belongs to the unit.

This helps with:

  * shutdown;
  * restart;
  * accounting;
  * memory limits;
  * CPU limits;
  * identifying the processes of a service;
  * isolation;
  * delegation to containers.

With cgroup v2, systemd organizes services, sessions, scopes and slices into a
hierarchy. The project's current documentation describes `system.slice`,
`user.slice` and `machines.slice` as standard parts of that tree.

This is a case in which systemd is deeply tied to Linux. And that is
intentional.

From Fedora's earliest documents, the project said it did not intend to be
portable to other Unix systems. The idea was to make aggressive use of Linux
kernel features.

For people who think “Linux first,” that is an advantage.

For people who value software that can move between Linux, FreeBSD, OpenBSD and
other Unix-like systems, it is exactly the opposite.

Socket activation
-----------------

Socket activation is another concept that is often mentioned without
explanation.

We normally think of it like this:

  start daemon
  ↓
  daemon opens port/socket
  ↓
  clients can connect

With socket activation, the service manager can open the socket first:

  systemd opens socket
  ↓
  client connects
  ↓
  service is started
  ↓
  socket is handed to the service

This makes it possible to start services on demand and, in certain scenarios,
parallelize dependencies: a consumer can begin working even while the process
that will handle the socket is still starting up.

It is not magic. The software must be compatible with the model, and not every
daemon benefits from it. But it is a powerful tool when applied correctly.

s6 also provides mechanisms related to socket activation. So, once again, this
is not a capability that only systemd can implement.

Timers and cron
---------------

`cron` is still great.

A line like:

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

is small, universally recognizable and perfect for many cases.

systemd timers solve the same kind of problem in a way that is integrated with
the service manager.

A `.timer` triggers a `.service`, which means the execution inherits the same
model for logs, dependencies, user, sandboxing, resource limits and status.

Timers also have useful features such as randomized delays, monotonic timers and
handling of runs that should have happened while the machine was powered off,
depending on the configuration.

The choice does not have to be religious. If I have half a dozen simple scripts
on a server, cron may be clearer. If the task is already managed as a service
unit and needs the same security and observability policy, a timer usually fits
better.

journald and the log war
------------------------

Perhaps no part of systemd has irritated traditional administrators as much as
journald.

The classic Unix model is comfortable:

  /var/log/syslog
  /var/log/messages
  /var/log/auth.log

and then:

  grep
  awk
  sed
  tail
  less

Text files are transparent, easy to copy, recover and analyze with tools that
have existed for decades.

journald chose its own structured format. You query it with:

  journalctl

and can filter by unit:

  journalctl -u nginx

by boot, PID, UID, priority, time interval and various other metadata fields.

The gain is real. A log is not merely a sequence of lines; each entry can carry
structured context. That makes operational questions very easy to answer.

The criticism is real too. You become dependent on tools that understand the
journal. `cat` is no longer enough to inspect the raw storage.

Simply saying that “binary logs are bad” is shallow. Databases and structured
formats do not become unsuitable merely because they are not plain text. The
question is whether the advantages of indexing and metadata outweigh the cost of
specific tools and more specialized recovery.

Another exaggerated claim is that journald prevents syslog. It does not. systemd
can coexist with traditional syslog implementations, and distributions can
forward messages according to their policy.

My reading is that the strongest criticism is not “binary = bad,” but rather
reduced replaceability through generic Unix tools. That is a much more
interesting architectural criticism.

Sandboxing without putting everything in a container
----------------------------------------------------

One of systemd's capabilities that administrators tend to underestimate is
`systemd.exec`.

A service unit can receive restrictions such as:

  [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=

These options belong to different families.

`NoNewPrivileges=yes` prevents the process and its descendants from gaining
privileges through mechanisms such as setuid executables.

`ProtectSystem=` and `ProtectHome=` alter the visibility and permissions of
parts of the filesystem.

`PrivateTmp=yes` creates a private view of temporary directories.

`PrivateDevices=yes` restricts access to devices.

`RestrictAddressFamilies=` limits socket families.

`MemoryMax=` and `CPUQuota=` use resource-control mechanisms.

`CapabilityBoundingSet=` reduces the available capabilities.

`SystemCallFilter=` can limit sets of syscalls.

This does not automatically turn an insecure program into a secure one.
Hardening requires understanding the service. A bad rule can break the
application or provide a false sense of isolation.

But for many small daemons, these options make it possible to impose useful
limits without creating a Docker container just to obtain basic isolation.

You can even analyze a unit with:

  systemd-analyze security name.service

and use the result as a starting point for review.

So why do people say systemd violates the Unix philosophy?
----------------------------------------------------------

The most repeated phrase is:

> Do one thing and do it well.

It represents a real tradition, but it is not a constitutional article of Unix.

The idea is to favor small programs, simple interfaces, composition and
replaceability. Tools should communicate through predictable mechanisms, often
text and pipes.

systemd was born from a different priority: coherent integration of system
management.

It uses many separate components, but those components share conventions,
libraries, APIs, unit formats, D-Bus and a common view of the system.

For its defenders, this eliminates duplication, solves cases that independent
scripts handled poorly and provides a consistent platform.

For its critics, it creates a central layer with too broad a reach.

Both are describing real aspects.

The discussion becomes poor when one side caricatures the other. It is not true
that every critic wants to return to a 1975 Unix. It is also not true that every
form of integration is automatically “anti-Unix.”

Scope creep: when an init stops being just an init
--------------------------------------------------

The project has grown substantially since 2010.

In addition to system/service management, the systemd ecosystem maintains
components related to logging, login and sessions, DNS, networking, time
synchronization, devices, temporary files, mounts, containers, boot, users,
credentials and home directories, among other areas.

This is where the scope creep criticism becomes stronger.

An administrator may like `systemd.service` and not want `systemd-resolved`.
They may use `journald` and prefer NetworkManager over `networkd`. On many
distributions, that is perfectly possible.

But the fact that components are optional does not eliminate the architectural
question. The project as a whole has become one of the major infrastructure
centers of Linux user space.

That brings integration gains and increases the number of decisions concentrated
in the same project.

A serious criticism does not need to claim that there is a conspiracy to
“dominate Linux.” It is enough to observe that concentration of responsibility
increases the technical and social impact of that project's decisions.

The real problem: ecosystem dependencies
----------------------------------------

At first, the question seemed to be:

  systemd vs another init

Today it looks more like:

  init
  login/session management
  udev
  D-Bus
  desktop environments
  service units
  cgroups
  packaging
  libraries
  distribution policies

This is the point that makes antiX and Devuan interesting.

It is not enough to replace `/sbin/init`.

Desktop software may expect interfaces provided by `logind`. Packages may
install only systemd units. Upstream documentation may assume `systemctl`.
Certain integrations may expect udev, cgroups or behavior defined by the systemd
ecosystem.

Projects without systemd need to decide how to fill those gaps.

Two names appear quite often:

elogind extracts systemd's login/session management functionality so that it can
be used independently of systemd as PID 1.

eudev emerged as an alternative/fork of udev for ecosystems that wanted less
dependence on the systemd suite. The device-management situation varies by
distribution, and some use other solutions, such as `mdev` on Alpine.

That is the difference between:

  “not installing systemd”

and:

  “maintaining a modern distribution without depending on the systemd ecosystem”

The second sentence describes ongoing integration work.

antiX: the example that brought me here
---------------------------------------

antiX

Example of an antiX desktop. Its appearance varies by version and window
manager.

antiX is an especially interesting case in 2026 because it did not simply choose
“the old init.”

antiX 26, released on March 21, 2026, offers five options:

  runit (default)
  SysVinit
  dinit
  s6-rc
  s6-66

That says a lot about the project's intent.

The focus remains lightweight operation, older machines and user control, but
the current strategy recognizes that there are modern alternatives to systemd,
not just SysVinit.

Runit provides real supervision. dinit has dependencies and parallelization. s6
provides a robust supervision-tree architecture.

So when someone summarizes antiX as “they do not use systemd because it is
heavy,” they miss the most interesting part.

antiX is choosing a different philosophy of composition.

Devuan
------

Devuan was born directly from Debian's decision to adopt systemd.

Its goal is not to pretend that the modern ecosystem does not exist. On the
contrary: Devuan has to do the work precisely to provide a Debian-like system
without systemd as PID 1.

The current migration documentation shows this almost didactically. When
migrating from Debian to Devuan, packages such as these appear:

  sysvinit-core
  eudev
  elogind

In other words, removing systemd requires replacing responsibilities that, on a
standard Debian system, are already integrated.

Devuan presents SysVinit as the default and also works with alternatives such as
OpenRC and runit.

If you want Debian without systemd, Devuan makes more sense than manually
ripping systemd out of a current Debian installation, because the distribution
takes responsibility for maintaining that choice.

Void Linux and runit
--------------------

Void is probably one of the best arguments against the idea that “without
systemd you are stuck with old technology.”

Void uses runit.

Runit is small, portable and focused on supervision. Each service has a
directory and usually a `run` script that executes the daemon in the foreground.

On Void:

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

Enabled services are linked into the supervised directory.

The runit documentation emphasizes an important point: the supervisor directly
knows the process it started, avoiding some of the historical fragility of PID
files and double daemonization.

The beauty of the model is that supervision is treated as the central problem,
without turning the supervisor into a platform for DNS, networking, login and
the bootloader.

That separation is exactly what attracts its users.

The price is that other functions need to be handled by other tools and by the
distribution's integration work.

Alpine Linux and OpenRC
-----------------------

Alpine uses OpenRC as its default init/service management system.

OpenRC keeps an experience very close to the script tradition, but adds explicit
dependency management and its own tools:

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

Alpine is important evidence because it is widely used in containers and
minimalist servers. Not using systemd does not prevent a Linux system from being
modern, supporting cgroup v2 or running current workloads.

It also shows that the cost exists. Package documentation makes it clear that
support scripts for different init systems need to be packaged. For certain
software, Alpine provides `-openrc` packages; other alternatives may not have
ready-made scripts.

Artix
-----

Artix occupies a niche similar to “Arch without systemd.”

The project offers variants with OpenRC, runit, s6 and dinit. The idea is to
provide the experience of an Arch-style rolling-release system while retaining
alternative init systems.

It is a good laboratory for anyone who wants to compare models without giving up
a modern desktop.

It also requires accepting that documentation written for Arch often assumes
systemd. At some point, you need to translate `systemctl enable --now x` into
the tool and model used by the variant you chose.

Gentoo
------

Gentoo follows a solution that fits its culture well: choice.

OpenRC is the historical and native option, while systemd is fully supported.

This coexistence is interesting because it demonstrates that both architectures
can be treated as first-class options when a distribution decides to invest in
maintaining both.

It is also a reminder that “without systemd” does not necessarily mean
“anti-systemd.”

The alternatives
----------------

SysVinit
--------

SysVinit is historically important and remains functional.

Its strengths are predictability, familiarity and an architecture that leaves
much of the work visible in scripts.

The problem is that, on its own, it does not provide as complete a modern answer
for supervision, process groups and dependencies.

Using it today usually involves combining it with other tools.

runit
-----

Runit is small and elegant.

Its strengths are:

  * simple supervision;
  * an easy-to-understand service model;
  * automatic restart;
  * a small codebase;
  * portability across several Unix-like systems.

It is excellent when you want the service to be a supervised foreground process
and prefer to build the rest of the system with independent tools.

OpenRC
------

OpenRC is a more natural evolution for people who like the traditional model.

It provides dependencies, runlevels and consistent management without taking on
the same scope as systemd.

It is especially attractive on Gentoo and Alpine because the distribution
ecosystem already does the integration work.

s6
--

s6 is perhaps the option that is most technically impressive among the
minimalist systems.

It starts from a small and robust supervision tree. The ecosystem includes
components for service management and init while preserving a philosophy of
composable tools.

The problem is ergonomics. For many people, the learning curve is steeper than
with runit and systemd.

This is improving with layers such as `s6-frontend`, but it remains a solution
that rewards those who want to understand the model deeply.

dinit
-----

dinit tries to occupy an interesting middle ground.

It is compact, but provides dependencies, parallel startup, controlled restart
and service management.

In 2026 it gained additional relevance: antiX 26 offers it as an option and the
project announced adoption by distributions such as KaOS.

Dinit proves that there is still practical research happening in the
init/service-manager space. The discussion did not end in 2015.

What people say about systemd that is not always true
-----------------------------------------------------

“systemd is one gigantic binary”
--------------------------------

No.

The project is large, but it contains several separate executables and daemons.
The correct criticism is about scope and integration, not about everything being
compiled into a single process.

“Everything runs inside PID 1”
------------------------------

No.

PID 1 runs the system/service manager. journald, logind, resolved, networkd and
others are separate processes when they are used.

“If journald gets corrupted, you necessarily lose all your logs”
----------------------------------------------------------------

That is an exaggeration.

Corruption is a legitimate concern for any structured storage system, but
journald has its own tools and mechanisms, and traditional syslog can coexist
with it.

The stronger criticism is dependence on specific tooling.

“systemd replaced all of Unix”
------------------------------

No.

It has taken on many infrastructure functions in modern Linux, but it still
coexists with shell, cron, syslog, NetworkManager, DNS servers, containers and
dozens of other tools when the distribution chooses to configure things that
way.

“systemd is always slower”
--------------------------

There is no serious basis for that generalization.

Boot time depends on hardware, services, distribution and configuration. The
architecture itself was designed for parallelization and on-demand activation.

It is also true that a minimalist system using runit may have fewer components
and boot very quickly. A benchmark without context is worth little.

“systemd only exists because Red Hat forced everyone to use it”
---------------------------------------------------------------

Red Hat had enormous influence because Fedora was the first major adopter and
Lennart Poettering worked there.

But Debian made its own decision after a long and contentious discussion. Arch,
SUSE, Ubuntu and other projects also had their own processes.

Influence is not the same thing as centralized imposition.

“Modern Linux does not work without systemd”
--------------------------------------------

antiX, Devuan, Void, Alpine, Artix and Gentoo demonstrate the opposite every
day.

What is true is that maintaining a modern Linux desktop without systemd may
require extra integration work.

“systemd is spyware”
--------------------

There is no technical basis for that claim as a description of the project.

“systemd is insecure by definition”
-----------------------------------

No.

Complexity increases the bug surface, and that deserves discussion. At the same
time, systemd provides sandboxing controls, capabilities, namespaces and cgroups
that can reduce the surface exposed by services.

Security needs to be analyzed in terms of threats and configuration, not
slogans.

“Anyone who dislikes systemd is nostalgic”
------------------------------------------

That is a caricature.

There are perfectly modern architectural criticisms concerning coupling,
portability, replaceability and concentration of responsibility.

“Alternatives are always simpler”
---------------------------------

No.

Runit is conceptually simple. A complete desktop system built around it may
require several additional pieces, scripts and decisions.

Simplicity of a component does not guarantee simplicity of the integrated
system.

The criticisms of systemd that make sense
-----------------------------------------

Once the exaggerations are separated out, quite a lot of serious material
remains.

1\. The scope is enormous
-------------------------

There is no denying it.

The project covers many areas of Linux user space. This increases the number of
architectural decisions that pass through the same ecosystem.

2\. Coupling is increasing
--------------------------

Even when a component is optional, third-party software may assume its
interfaces.

An alternative distribution needs to track upstream projects, maintain scripts,
adapt dependencies and provide replacements.

3\. Portability is not a goal
-----------------------------

systemd is deliberately Linux-specific.

If your view of Unix values software that can be shared between Linux and BSD,
that is a structural disadvantage, not a minor detail.

4\. Debugging can be abstract
-----------------------------

When everything works, `systemctl status` and `journalctl` are excellent.

When a unit enters a strange state because of a dependency, generator, override,
target or cgroup interaction, you need to understand the systemd model. “It is
declarative” does not mean “it is always simple.”

5\. There is a concentration of responsibility
----------------------------------------------

A bug or change in systemd infrastructure can affect many distributions at the
same time.

That is the other side of standardization.

The strengths that also need to be taken seriously
--------------------------------------------------

Service supervision
-------------------

systemd manages services throughout their entire lifecycle, not only during
boot.

Cgroups
-------

The ability to track every process in a unit and apply limits is excellent for
servers.

Declarative units
-----------------

For many services, a `.service` file is smaller and less ambiguous than full
init scripts.

Consistent tools
----------------

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

work in a similar way across a huge number of distributions.

Sandboxing
----------

It is possible to apply isolation policies directly to the service.

User services
-------------

Per-user services are very useful for desktop applications and persistent
agents.

Timers
------

They integrate scheduling into the same supervision, logging and security model.

Documentation and support
-------------------------

Mass adoption has created a huge amount of documentation, examples and available
operational knowledge.

Integration with modern Linux
-----------------------------

If you want cgroups v2, containers, resource management, sessions and services
working within the same model, systemd is a very capable solution.

A slightly more hardened example
--------------------------------

Taking the simple unit:

  [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 is not merely starting `/usr/local/bin/example`.

It is defining a restart policy, creating a more restricted filesystem view for
the process and limiting memory.

That is why saying “systemd is only for boot” stopped making sense a long time
ago.

Would I manually remove systemd from a modern Debian system?
------------------------------------------------------------

On an ordinary Debian server, no.

Not because it is impossible. Because the cost-benefit ratio is poor.

Debian tests its packages, documentation and integration assuming systemd as the
default. By removing it, you become responsible for solving incompatibilities
that a distribution such as Devuan has already taken on as part of its mission.

If there is a concrete need not to use systemd, I would choose a distribution
built for that.

For a minimalist server, Alpine or Void can be excellent choices.

For a Debian-like system without systemd, Devuan is far more sensible.

For experimenting with different philosophies, antiX 26 has become a
particularly fun laboratory.

For those who want maximum control and are willing to invest the time, Gentoo
remains one of the most flexible options.

Removing systemd from Debian just to prove that it can be done tends to turn an
architectural preference into unnecessary operational work.

What about servers?
-------------------

On servers, systemd is usually a practical advantage.

Cgroups, resource limits, restart policies, logs, hardening and uniform
administration are useful.

On hosts running Docker or Podman, systemd on the host and the container runtime
operate at different levels. systemd can manage the daemon/runtime and the
cgroup tree; inside small containers, there is usually no need to run a full
service manager.

There is a subtlety here: every container also has a PID 1 inside its namespace.
Sometimes a tiny init is used for proper signal handling and reaping. In
containers that actually represent a complete system, systemd can be used as PID
1, provided cgroups and permissions are configured appropriately.

In other words, containers did not make init systems irrelevant. They merely
moved part of the discussion.

What about the desktop?
-----------------------

The average user probably does not notice systemd directly.

They notice that the session starts, the laptop suspends, devices appear, audio
works, the network comes up and user applications start.

Behind that are login/session-management components, udev, D-Bus, per-user
services and desktop integrations.

That is why removing systemd from a desktop can be more work than removing it
from a very simple server. The problem is not just starting `nginx`; it is
integrating a graphical stack full of expectations.

Distributions without systemd solve this with elogind, eudev/mdev, scripts and
desktop-specific choices.

Does the controversy still make sense in 2026?
----------------------------------------------

Yes, but it has changed.

In 2014, the question was whether systemd should win.

In 2026, it has already won as the dominant default among the major Linux
distributions.

The interesting discussion now is different: how much of Linux user space should
converge around it, and how much room is worth preserving for alternative
architectures?

That question remains healthy.

The fact that antiX 26 offers five init systems is almost a practical answer to
the argument that the subject is settled. Void continues to show that runit is
enough to build a modern distribution. Alpine demonstrates that OpenRC and
cgroup v2 coexist perfectly well. Gentoo maintains two well-supported paths.
Dinit continues to evolve. s6 continues to explore an extremely modular view of
supervision.

At the same time, systemd has become better, more mature and harder to dismiss
as “a bloated init.”

It solved real problems.

Supervision is better than hunting for PID files. Cgroups are better than
guessing process trees. Declarative units are excellent for packaging. Timers,
sandboxing and user services are practical tools. On a modern Debian, Fedora,
Arch or Ubuntu system, there is very little operational reason to rip it out
without a specific need.

But the criticisms concerning scope, coupling, portability and replaceability
remain valid.

After researching the subject, my position became less dramatic than the history
of the controversy tends to suggest.

I would not remove systemd from a distribution whose entire ecosystem was built
and tested around it. On Debian servers, for example, it gives me more
advantages than problems.

I also would not want a Linux world in which the alternatives ceased to exist.

Projects such as antiX, Void, Alpine, Devuan, Artix and Gentoo act as a form of
architectural diversity. They keep different ideas about supervision, init,
composition and portability alive. Some of those ideas may even influence the
mainstream in the future.

That is what I did not understand when I started reading about antiX.

The question is not really “why does anyone hate systemd?”

The question is: how much integration do we want to concentrate in a central
layer of the system, and how much are we willing to pay to preserve replaceable
components?

The answer depends on the system we are building.

And that is much more interesting than “systemd is heavy.”

*

Sources and recommended reading
-------------------------------

systemd
-------

  * systemd.io [1]
  * Control Group APIs and Delegation [2]
  * systemd Optimizations [3]
  * systemd man pages, freedesktop.org [4]

Adoption history
----------------

  * Fedora: Features/systemd [5]
  * Debian Technical Committee: default init system for Debian [6]
  * Debian General Resolution: init system coupling [7]

Distributions without systemd as the default
--------------------------------------------

  * antiX 26 download/release information [8]
  * Devuan: Init Freedom [9]
  * Devuan: migration from Debian to Excalibur [10]
  * Void Linux Handbook: Services and Daemons / runit [11]
  * Alpine Linux: OpenRC [12]
  * Gentoo Handbook / init choices [13]
  * Artix Linux [14]

Alternatives
------------

  * runit [15]
  * runit: benefits [16]
  * s6 [17]
  * s6 overview [18]
  * s6-frontend [19]
  * Dinit [20]
  * Dinit service descriptions [21]
  * OpenRC [22]

Links:
  [1] https://systemd.io/
  [2] https://systemd.io/CGROUP_DELEGATION/
  [3] https://systemd.io/OPTIMIZATIONS/
  [4] https://www.freedesktop.org/software/systemd/man/latest/
  [5] https://fedoraproject.org/wiki/Features/systemd
  [6] https://lists.debian.org/debian-devel-announce/2014/02/msg00005.html
  [7] https://www.debian.org/vote/2014/vote_003
  [8] https://antixlinux.com/download/
  [9] https://www.devuan.org/os/init-freedom
  [10] https://beta.devuan.org/os/documentation/install-guides/excalibur/trixie-to-excalibur.html
  [11] https://docs.voidlinux.org/config/services/
  [12] https://wiki.alpinelinux.org/wiki/OpenRC
  [13] https://wiki.gentoo.org/wiki/Handbook:AMD64
  [14] https://artixlinux.org/
  [15] https://www.smarden.org/runit/
  [16] https://www.smarden.org/runit/benefits
  [17] https://skarnet.org/software/s6/
  [18] https://skarnet.org/software/s6/overview.html
  [19] https://skarnet.org/software/s6-frontend/
  [20] https://davmac.org/projects/dinit/
  [21] https://davmac.org/projects/dinit/man-pages-html/dinit-service.5.html
  [22] https://github.com/OpenRC/openrc


< the skull