Generally you don't specify a specific version as a dependency unless it's necessary, but when 'building' the system, specific versions are used. If things break during an upgrade you can roll back to the previous version. Keeping those older builds around will mean keeping older versions of the packages used in those builds (libcurl, for example). Periodically, you can purge older generations (i.e. builds) and collect garbage, which will clear out packages that aren't used anymore. It would be very strange to end up in a situation where you had dozens of instances of libcurl _being used simultaneously_ (though I guess that would be possible if lots of packages had very special requirements, and ended up building libcurl with different flags or something).
There may be circumstances where you have a _specific_ version dependency, and you can specify that too. That would mean having multiple copies of the same package, even in a single generation. Obviously this usually means major versions, so you don't usually see _dozens_ of them. Having specific dependencies on minor versions would be a major code smell IMHO.
Anecdotally, my NixOS systems (both desktops and servers) can grow up to, say, ~50 gb of system files in a few months, at which point I'll clear out older generations and GC, which gets them down closer to a typical Linux distro size. Once or twice, I've seen a system balloon up over 100G when I was doing a lot of experimenting with packages.
Oh, and incidentally, most of the different versions are only visible to the packages that depend on them. Your 'default' environment is one such package, and only sees one of each of it's dependencies. It's not like you have dozens of instances of packages crowding /lib or anything (since /lib doesn't exist in the first place). You have to go looking in the Nix package store to find the actual files.
- Traditional distro: you cannot end up with that
- Flatpack, snap etc.: you cannot avoid that
Nixpkgs doesn't wontonly package multiple versions of libraries. But as you upgrade you will accumulate old builds of libraries until you GC. The meaningful question is not how many of X do you have installed, but whether you have multiple versions of X reachable from GC roots.
The old libcurl will still exist on your system to allow you to rollback to previous states of your system, but you can always run nix-collect-garbage if you want to free up disk space.
This is similar to the situation in Arch Linux where pacman keeps all downloaded packages, and you have to run paccache if you want to free space.
- libcurl is 615,616 bytes
- curl itself is another 192,480 bytes
Not counting man pages.