Lix 2.95 prepares the daemon for new RPC protocols
Lix 2.95 adds infrastructure for multiple daemon protocols and improves the configuration and diagnostics around builds.
Replacing a build daemon protocol requires a period when the old and new implementations can coexist. Lix 2.95 adds internal support for multiple daemon sockets with different protocols, according to its March 25 announcement. That is the concrete RPC milestone in this release. The 2.95.0 release notes date the release itself to March 13.
The distinction between groundwork and a completed protocol replacement matters. Lix has been integrating Cap'n Proto in communication with helper programs. The announcement places an experimental local daemon protocol in the next development cycle, with remote build support and replacement of existing SSH store protocols as later aims. Those are plans as of March 25.
Nix and NixOS manage the desired state of my personal infrastructure. The declarative model is the reason I accept the language's awkward parts. A configuration still depends on an implementation that evaluates it and arranges its builds. Changes to that implementation's daemon and diagnostics therefore matter even when the configuration's intended result stays the same.
A protocol migration needs a coexistence mechanism
The announcement describes earlier releases as establishing the feasibility of Cap'n Proto integration. This release creates room to expose new protocols when they are ready. Separate sockets provide a way to make those protocols available without claiming that every existing client has already migrated.
That sequencing is sensible for infrastructure software. A daemon and its clients may have different update schedules. An implementation needs somewhere to exercise new communication behavior while retaining a usable path for existing clients. The presence of a new socket mechanism does not, by itself, prove compatibility or settle which client should use which protocol.
The Cap'n Proto RPC documentation describes an object-oriented capability protocol, with calls made on references to remote objects. It also describes promise pipelining, which lets a client send calls that depend on a previous result before waiting for that result to arrive. These are mechanisms an RPC system can provide, rather than evidence of a measured improvement in Lix 2.95.
A build system has to preserve more than message encoding during a protocol change. It needs to preserve the meaning of operations and their failure behavior. A successful serialized request is only one part of that requirement. The announcement's staged migration leaves space to establish those implementation properties before replacing the existing routes.
Socket activation changes how the daemon runs
The release notes say systemd-based installations now use socket activation instead of a persistent daemon process by default. The announcement describes instanced service units and notes their value for observing individual connections. It also names this arrangement as necessary infrastructure for the cgroups-related work.
That is an operational change with a direct deployment implication. The announcement warns that nix-daemon@.service must be available during upgrades or connections fail. The unit definition is therefore part of the working installation, alongside the daemon binary. Updating only an executable would miss a dependency of the new activation arrangement.
The notes also retain the persistent daemon behavior as an alternative, with mutual exclusion between the two modes. This gives the operational change a defined boundary. It changes how the service is started and supervised, while the protocol migration remains separate work.
For my use of declarative infrastructure, that boundary is useful. A system configuration should describe the service arrangement needed by the selected package. A daemon that relies on a matching unit template makes package and service configuration part of the same upgrade decision. The relevant artifact is the complete installed service configuration.
Remote builder configuration becomes named data
Lix 2.95 adds a TOML format for remote builders while retaining the legacy format. The remote build manual documents machine entries under a machines map. A small example can state its fields without depending on their position:
version = 1
[machines.builder]
uri = "ssh-ng://nix@builder.example"
system-types = ["x86_64-linux"]
jobs = 2
speed-factor = 1.0
This is an illustrative builder declaration. The address must identify an actual configured build machine before it is useful. The manual defines jobs as the maximum number of parallel builds assigned to that machine and speed-factor as a relative preference used when suitable machines are available.
Naming those fields helps review configuration changes. A reader can see that a number is a concurrency limit without counting columns. The explicit format version also gives future parsing rules a place to attach. The manual recommends including it in files so the interpretation does not silently track whichever version becomes current later.
The transport remains ssh-ng in this example. A clearer configuration format does not imply the planned new RPC transport has shipped. Both changes support the build system, but they operate at different points in its configuration and execution.
Evaluation warnings get a direct interface
The release adds builtins.warn, which takes a string and an expression to return. Its related options allow entering the debugger on a warning or aborting evaluation. A warning can therefore become useful to both an interactive user and an automated check without requiring two separate messages in expression code.
The release notes also make log-format a configuration setting and document the following persistent choice:
log-format = multiline-with-logs
These changes are smaller than a daemon protocol redesign, but they affect how users understand evaluation and build failures. A warning has a defined control path. A log preference can live in configuration. Both reduce the amount of command-specific context a user has to reconstruct when a build behaves unexpectedly.
Performance work targets repeated launch overhead
The release notes report lower Linux sandbox launch overhead, particularly for graphs containing many small derivations. Their synthetic example builds 3,000 small runCommand derivations in 14 seconds instead of 80 and explicitly identifies this as an optimistic case. It should not be read as a prediction for every NixOS build.
The mechanism matters more than applying that ratio universally. When each derivation does little work, repeated launch management can account for a large part of elapsed time. Reducing that overhead helps a different workload from one dominated by a long compiler invocation. Lix 2.95 combines those immediate implementation improvements with the daemon infrastructure needed for its next protocol work.