Direnv + nix-shell is very slow after the last update

Hey, I am using nixos-unstable, and I’ve noticed that switching to direnv directory with envrc became significantly slower since about a week ago. It went for less then a second to 10 seconds and a bit.

Here’s the setup I use

$ cat .envrc 
use nix

$ cat shell.nix 
with import <nixpkgs> {};
mkShell {
  LIBCLANG_PATH = "${llvmPackages_13.libclang.lib}/lib";
}

Cursiously, nix --version is also excruciatingly slow for me (not sure if that’s a regression or a per-existing behavior):

$ t nix --version
nix (Nix) 2.3.16

real 10.02s
cpu  0.00s (0.00s user + 0.00s sys)
rss  17.38mb

Has anybody else seen this? What might be the issue?

Quick strace of nix --version shows this:

socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3
setsockopt(3, SOL_IP, IP_RECVERR, [1], 4) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.0.1")}, 16) = 0
poll([{fd=3, events=POLLOUT}], 1, 0)    = 1 ([{fd=3, revents=POLLOUT}])
sendmmsg(3, [{msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="*k\1\0\0\1\0\0\0\0\0\1\4this\17pre-initialize"..., iov_len=75}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=75}, {msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="Zi\1\0\0\1\0\0\0\0\0\1\4this\17pre-initialize"..., iov_len=75}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=75}], 2, MSG_NOSIGNAL) = 2
poll([{fd=3, events=POLLIN}], 1, 5000)  = 0 (Timeout)

Ie, something tries to do some networking and times out :scream:

What is the output of nix-channel --list; echo; sudo nix-channel --list; printenv NIX_PATH?

edit

The network access happens for me as well (192.168.178.1 is my local router):

$ strace nix --version 2>&1 | grep -A1 'inet_addr("192.168.178.1'
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.178.1")}, 16) = 0
poll([{fd=3, events=POLLOUT}], 1, 0)    = 1 ([{fd=3, revents=POLLOUT}])
--
recvfrom(3, "\342\16\201\203\0\1\0\0\0\1\0\1\4this\17pre-initialize"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.178.1")}, [28 => 16]) = 150
poll([{fd=3, events=POLLIN}], 1, 4997)  = 1 ([{fd=3, revents=POLLIN}])
--
recvfrom(3, "\242\v\201\203\0\1\0\0\0\1\0\1\4this\17pre-initialize"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.178.1")}, [28 => 16]) = 150
close(3)                                = 0
1 Like

We’re you using nix-direnv at some point? If so, perhaps it broken somehow and you are now missing it’s improved caching benefits over the default use nix function for direnv?

Bingo! I didn’t realize that 192.168.0.1 is a router, I thought that that’s localhost. Yeah, it seems that nix is generally unrelated, and that my router’s config got borked after a recent reboot :sweat_smile:. You saved so many n * 10 seconds of my life, thanks!

Though, I am still wondering why nix --version has to do a dns lookup…

EDIT: opened https://github.com/NixOS/nix/issues/5441 just in case.