reasons systemd is hostile to simplicity, choice, debuggability, and the unix tradition.

it is not an init system

systemd started as a replacement for sysvinit and quickly absorbed logging, device management, network configuration, time synchronization, login handling, dns resolution, container management, and more. the result is a single massive project that touches nearly every part of userspace. an init system should start processes and stay out of the way. systemd turned itself into the operating system.

unix philosophy is optional

the classic design rule was "do one thing and do it well." systemd does dozens of things and does several of them poorly. each new component increases the surface area, the attack surface, and the number of ways the whole machine can fail. when everything is tightly coupled, a bug in the journal or in udev can take down the boot process. modular tools can be replaced or ignored. a monolith cannot.

binary logs by default

journald stores logs in a binary format. plain text files that can be read with cat, grep, tail, and less are treated as second-class. binary logs require special tools, make remote collection more complicated, and turn simple debugging into an exercise in journalctl flags. when the journal itself is corrupted or the system is partially broken, the logs become harder to recover. text files fail more gracefully.

scope creep without end

every release seems to absorb another traditional daemon. networkd, resolved, timesyncd, homed, and the rest expand the project's reach. the official justification is always "integration" or "consistency." the practical effect is that distributions that ship systemd slowly lose the ability to swap individual components. once the dependencies are baked in, "optional" becomes theoretical.

hard to replace

many packages and desktop environments now assume systemd is present. dbus activation, cgroup management, and various unit files create soft lock-in. switching to another init requires fighting the packaging system and often rebuilding or patching software. the more software is written against systemd apis, the harder it becomes to leave. this is the opposite of the loose coupling that made unix systems durable.

complexity as a feature

unit files, drop-ins, generators, targets, slices, scopes, and a large configuration surface make simple tasks verbose and error-prone. the documentation is long because the system is large. newcomers are told to learn an entire parallel vocabulary instead of editing a few scripts. complexity is sold as power. in practice it is a tax paid every time something goes wrong at boot.

debugging becomes archaeology

when a service fails to start, the path to understanding often involves journalctl, systemctl status, systemctl cat, and various show commands. the old model of readable init scripts and clear process trees has been replaced by a state machine whose internal decisions are not always obvious. failures that used to be visible in a few lines of shell now require specialized knowledge of systemd internals.

cgroups as a control plane

systemd makes heavy use of cgroups and treats them as a central mechanism for resource control and process tracking. while cgroups are useful, making them mandatory infrastructure increases the minimum complexity of the system. other init systems can use cgroups when needed without requiring every service to be managed through the same hierarchy.

non-portable by design

systemd is tightly bound to linux kernel features. it is not intended to run on other unix systems and makes little effort to remain portable. this is a deliberate choice, but it means the largest free init system is also the one least useful outside the linux monoculture. portable tools survive platform changes. platform-specific megaprojects do not.

the "everything is a unit" worldview

services, sockets, mounts, timers, paths, and devices are all forced into the same abstraction. the uniformity looks elegant on paper. in practice it means that simple cron jobs become timer units, simple mount points become mount units, and operators must learn systemd's model even for tasks that never needed it. not every problem benefits from being expressed as a unit file.

security theater and real risk

a large codebase written in c with a wide attack surface is hard to secure. systemd has had its share of vulnerabilities. the project also pushes features such as dynamic users, private tmp, and various sandboxing options. some of these are useful. others add complexity that itself becomes a source of misconfiguration. security is improved more by reducing the amount of privileged code than by adding more configuration knobs.

desktop and server are conflated

features useful for a graphical workstation (session management, seat handling, user units) are carried into server environments where they add little value and extra moving parts. the same binary is expected to serve both roles. the result is that minimal server installs still pull in machinery designed for laptops and desktops.

dependency hell for distributions

once a distribution commits to systemd, reversing the decision becomes extremely expensive. packages start depending on libsystemd, on specific unit behaviors, and on journald. alternative inits are relegated to niche ports or abandoned. the cost of switching rises every year. this is how soft monopolies form in free software.

the cult of integration

proponents argue that tight integration produces a better user experience. the counter-argument is that integration without clear boundaries produces systems that are difficult to understand, difficult to repair, and difficult to replace piece by piece. unix succeeded in part because components could be swapped. systemd optimizes for a single coherent stack at the expense of that flexibility.

documentation reflects the size

the manual pages and the design documents are extensive because they have to be. learning enough to administer a systemd system confidently takes far longer than learning a traditional init. the knowledge is also less transferable. experience with one set of shell scripts translates more easily across systems than experience with one particular unit dialect.

boot becomes a black box

parallel startup, socket activation, and generator scripts make the boot process faster on paper and more opaque in practice. when something fails early, the failure mode is often a long wait followed by a rescue shell or a cryptic journal entry. linear, predictable scripts are slower but easier to reason about when the machine will not come up.

the replacement problem

systemd did solve real problems with sysvinit: lack of dependency handling, poor parallelization, and awkward service supervision. those problems could have been fixed with smaller, more focused tools. instead the solution was a single project that kept growing. the existence of a real problem does not justify an unbounded solution.

community and governance

the project is tightly controlled. technical disagreements frequently become personal. critics are often dismissed as anti-progress or as people who simply do not understand modern systems. the result is a culture that produces a lot of code and relatively little willingness to question the overall direction. large projects need internal resistance to scope creep. systemd has shown limited capacity for that resistance.

it trains developers to stop thinking

when the init system handles restart policies, resource limits, dependency ordering, and logging, application developers are encouraged to treat the service manager as a black box. the old discipline of writing programs that behave well under simple supervision is weakened. the system becomes smarter so that individual components can become dumber. that tradeoff is not free.

better alternatives

you do not have to accept systemd as the only modern option.

init systems and service managers

logging

device and network management

distributions that do not force systemd

(c) 2026 vextoly

Please don't upload to GitHub