When we started building NovaPulse, one of our earliest architectural decisions was choosing a container runtime. Docker was the obvious choice — it is what everyone uses, right? But after months of testing, we made the unconventional decision to build on systemd-nspawn instead. Here is why.
The Problem with Daemons
Docker requires a long-running daemon process (dockerd) that manages all containers on a host. This creates a single point of failure — if the daemon crashes, every container on the host goes down. For a platform built around scale-to-zero, where containers are constantly being frozen and thawed, daemon reliability is critical. With systemd-nspawn, each container is a direct child of PID 1 (systemd). There is no intermediary daemon. If one container crashes, nothing else is affected.
Native cgroup Integration
Our scale-to-zero technology relies heavily on cgroup v2 for freezing containers at the kernel level. systemd-nspawn containers are native systemd units, which means they get first-class cgroup management out of the box. We can freeze a container with a single systemctl freeze command, and the kernel handles the rest — no custom cgroup manipulation needed.
Simplicity and Debuggability
systemd-nspawn is a single binary with a straightforward set of options. There is no image layering system, no build cache, no complex networking overlay. It boots a full Linux userspace in a namespace — and that is it. When something goes wrong, you can debug it with standard Linux tools: journalctl, systemctl, nsenter, machinectl. No need to learn a separate ecosystem of Docker-specific debugging tools.
The Trade-offs
This choice was not without trade-offs. We had to build our own image distribution system (which became NovaPulse’s content-addressed storage layer). We had to implement our own networking stack. And we lost access to Docker’s massive ecosystem of pre-built images — though we built a compatibility layer that can import OCI images into nspawn containers.
But the benefits — no daemon, native cgroup integration, kernel-level freeze/thaw, and radical simplicity — made systemd-nspawn the right foundation for what we are building. Sometimes the unconventional choice is the correct one.