Two boxes, two philosophies

I run Fedora Server on my T620 NAS and NixOS with KDE Plasma on my daily driver desktop. Not a lab experiment, not “let me try this for a week and write a hot take” … these are both machines I actually depend on every day, which means whatever broke, I had to actually fix, not just note down and move on.

Fedora: familiar, fast to fix, one config file at a time

Fedora Server feels like driving a car you already know how to drive. Something breaks, you find the config file, you edit it, you restart the service. dnf, systemctl, /etc/. No new mental model required.

Where it earns its keep is the small, boring stuff. Wrong I/O scheduler for a NAS workload? One udev rule, done, persists across reboots without having to think about it again:

sudo tee /etc/udev/rules.d/60-ioscheduler.rules << 'EOF'
ACTION=="add|change", KERNEL=="sda", ATTR{queue/scheduler}="mq-deadline"
EOF
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=block

SELinux context wrong on a directory that needs to serve two different services? Same pattern every time, no surprises:

sudo semanage fcontext -a -t public_content_rw_t "/some/path(/.*)?"
sudo restorecon -Rv /some/path

The downside only shows up later. Six months from now, if that box needs rebuilding, I have to remember every single one of these one-off tweaks myself, or dig through my own notes and hope I wrote them down properly. Fedora doesn’t know what I changed. Only I do.

NixOS: everything lives in one place, whether you like it or not

NixOS flips that completely. Instead of scattered /etc/ edits, every change is a block of config in a .nix file, and the entire system … services, packages, users, systemd units … gets rebuilt from that description every time.

That sounds academic until something actually breaks repeatedly and you get sick of fixing it by hand. My desktop kept losing WiFi after suspend. Instead of running systemctl restart NetworkManager every single time I woke the machine, I wrote it once, as a real system service tied to the suspend target:

systemd.services.nm-resume-fix = {
  description = "Restart FUCKING NetworkManager after resume";
  after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
  wantedBy = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
  serviceConfig = {
    Type = "oneshot";
    ExecStart = "${pkgs.bash}/bin/bash -c 'sleep 2 && systemctl restart NetworkManager'";
  };
};

Same story when the screen kept coming back dim after every resume … not an actual brightness problem, KWin’s own render state getting stuck. Once I found the right fix, it went into the config as its own service instead of a command I’d have to remember to run manually forever:

systemd.services.kwin-resume-fix = {
  description = "Reconfigure the FUCKING KWin after resume";
  after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
  wantedBy = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
  serviceConfig = {
    Type = "oneshot";
    ExecStart = "${pkgs.bash}/bin/bash -c 'sleep 2 && qdbus org.kde.KWin /KWin reconfigure'";
  };
};
sudo nixos-rebuild switch

That’s the whole appeal. Every fix I’ve ever needed on this desktop is sitting in version-controlled files right now. If this machine died tomorrow and I rebuilt from the same config on new hardware, every one of these annoyances would already be solved before I even logged in.

Where NixOS actually costs you time

It’s not free. The declarative model means even small things go through an extra layer of indirection … you don’t just systemctl restart a user service and move on, you have to know whether it’s a system service or a user service, because they live in genuinely different places in the config:

systemd.services.something = { ... };       # system-level
systemd.user.services.something = { ... };  # session-level, different key entirely

Get that wrong and the whole rebuild fails with an option-doesn’t-exist error that doesn’t always point at the actual mistake clearly. I’ve lost real time to exactly that … a service nested one level too deep in the wrong block, config builds fine syntactically, just silently means nothing you wrote actually does what you think.

Debugging in the moment is also just slower. Fedora, I edit a file and restart a service in ten seconds. NixOS, every change is a full nixos-rebuild switch … usually quick, but it’s still a build step in the loop every single time, even for a one-line tweak.

The actual verdict

For the NAS … Fedora, no contest. It’s a server that mostly just needs to run and rarely gets touched once it’s stable. I don’t need reproducible infra for a box I’m not planning to nuke and rebuild every month. Quick, direct config edits are the right tool there.

For the desktop I actually sit at every day, making changes to constantly … NixOS wins, specifically because I keep hitting the same category of annoying, recurring bugs (resume glitches, one-off tweaks I’d otherwise forget). Every fix becomes permanent the moment it’s in the config. I’m not fixing the same problem twice.

Neither one is “better” in the abstract. It’s genuinely about how often you touch the box and whether you’d rather remember your fixes yourself, or have the system remember them for you.