Shared pkgs
yen’s own part of a host’s evaluation is small: 1.4% on the reference fleet’s lb. Most of the time goes to
nixpkgs pkgs (56%) and the NixOS module system (36%). By default every host imports nixpkgs again.
With sharedPkgs = true, a host reuses the pkgs of the first sharing host on its system (the leader),
through nixpkgs’ readOnlyPkgs module. The out arg gives the leader’s built pkgs, lazily.
# Hosts with `sharedPkgs` reuse the pkgs of the first sharing host (the leader): nixpkgs is imported once.{ yen, lib, inputs, ...}:let np = inputs.nixpkgs;in{ yen.kinds.fleet = { spawns.host = _: yen.host; sinks.out.reduce = yen.lib.reduce.merge; }; yen.kinds.host = { fields = { system = yen.lib.opt lib.types.str "x86_64-linux"; sharedPkgs = yen.lib.opt lib.types.bool false; }; sinks.nixos.out = { host, nixos, out, ... }: let group = lib.sort (a: b: a < b) ( lib.attrNames (lib.filterAttrs (_: h: h.sharedPkgs && h.system == host.system) yen.host) ); # one group per system leader = lib.head group; follower = host.sharedPkgs && leader != host.name; shared = out.nixosConfigurations.${leader}.pkgs; # the `out` arg: the leader's built pkgs, lazily readOnly = [ np.nixosModules.readOnlyPkgs { options.nixpkgs.system = lib.mkOption { internal = true; }; } { nixpkgs.pkgs = shared; } ]; in { nixosConfigurations.${host.name} = np.lib.nixosSystem { inherit (host) system; modules = nixos ++ lib.optionals follower readOnly; }; ownPkgs.${host.name} = np.lib.nixosSystem { inherit (host) system; modules = nixos; }; # the oracle: the same host with its own pkgs }; };
yen.fleet.main = { }; yen.flake = { out, ... }: out;}{ yen, lib, ... }:{ yen.host = lib.genAttrs [ "app-1" "app-2" "app-3" ] (_: { sharedPkgs = true; }); yen.aspects.app = { at = yen.kinds.host; nixos = { host, pkgs, ... }: { networking.hostName = host.name; environment.systemPackages = [ pkgs.htop ]; boot.loader.grub.device = "nodev"; fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; }; system.stateVersion = "25.05"; }; }; # docs differ when pkgs is shared: keep them off on sharing hosts yen.aspects.shared-no-docs = { at = yen.lib.all [ yen.kinds.host (s: s.sharedPkgs) ]; nixos.documentation = { enable = false; nixos.enable = false; man.enable = false; }; };}The oracle
Section titled “The oracle”A follower must build exactly what it builds alone. ownPkgs is each host built with its own pkgs.
The docs check that every host’s toplevel drvPath is the same both ways.
| Reference fleet: lb, web-1, web-2 toplevel | CPU | Thunks | GC total |
|---|---|---|---|
| each its own pkgs | 35.3 s | 36.6 M | 2.71 GB |
| shared pkgs | 24.8 s | 29.3 M | 1.96 GB |
Measured on the reference fleet, with the same drvPaths both ways
(README).