I’m a base model macOS user (just 256 GB of internal storage), and while I love using Nix, the limited disk space isn’t enough for my work needs. So I’ve been using an external SSD to help with storage.
I’m still a beginner with Nix, but I do have a standard bare-metal setup on my internal drive. Now, I want to extend or migrate part of this setup to the SSD—but with a twist.
What I’m trying to do
I want to maintain two Nix configurations:
“Light” configuration (on internal disk): Contains frequently used, lightweight apps—things I use daily, even when I’m not doing heavy development.
“Heavy” configuration (on SSD): Contains everything in “light” plus large, storage-heavy apps/tools that I don’t need all the time.
What I’d like is for my system to automatically:
Use the light configuration and internal Nix store when the SSD is not connected.
Switch to the heavy configuration and external Nix store when the SSD is connected.
Is this even possible?
I’ve read that you can change the Nix store location using environment variables or by symlinking /nix/store, but what I’m aiming for is a bit more dynamic and automatic.
Some ideas I’m exploring:
Use two different Nix profiles or flake configurations (light and heavy) and switch between them based on whether the SSD is mounted.
Mount the SSD’s /nix/store to /nix/store directly (possibly using a systemd mount or automount script), but I’m concerned about what happens to running applications when switching the store.
Apps already in memory should keep working unless they need to access the store again, right?
But is this switching behavior even safe or supported?
I’m totally fine with having to stop background apps or even reboot during the switch—what matters most is that the system can work cleanly with this dual setup.
Has anyone tried something similar, or does anyone have recommendations on how best to approach this?
I don’t think I’d want to try this without rebooting when switching.
Switch out all of /nix, not just /nix/store. The nix db, profile links, and all the other stuff in /nix are tightly coupled to the store itself. Lots will go wrong if they aren’t kept together.
You’ll now need to update everything in the light config twice. Once on the light config, and once on the heavy. For me, personally, I suspect that would be prohibitively annoying.
You need to specifically care for every symlink into the nix store that exists on the system during a switch, or it will likely become a dead link and possibly get automatically removed for that reason, even though it still exists on the other store. Depending on what all you do with nix, this might be a little bit manageable, or hopelessly impossible.
the switching mechanism you’re imagining is called specialisations
there is an experimental overlay store that could probably be used to support something like this
With that said, I’d also give some consideration to whether you really want this, and whether something else might work almost as well:
do you have good network connectivity?
do you follow the unstable branch, in which things are reasonably-often rebuilt and replaced wholesale every few weeks when staging merges
do you use the large things that would be in the overlay store all together at once, or this one or that one or the other one occasionally, such that any given one is used even more rarely?
If the answers to these questions are all essentially “yes” then you may simply get away with not having them installed at all, and just grabbing the current version of one or the other on-demand. Good ways to do this include:
nix-shell, nix shell, nix run, or comma to start them as needed
moving them from your system config to a project devshell, and not caching the devshell when not in use (as nix-direnv would normally do)
This exchanges storage space for some extra startup latency, but if your bandwidth is good it’s probably not much worse than going and finding the usb device and connecting it. It also means the processes won’t fail if the removable device is accidentally unplugged, and may just be less fuss.
If the programs are used rarely, it saves time and bandwidth grabbing updates for all that data possibly several times between actual uses.
All this is probably also true for projects that also have large data, and where the data lives on the external device as well. But in that case there’s probably also another option, which would be an imperative nixos container entirely on the ssd, with its own store for everything, that you enter and update separately when working on such a project.