diff --git a/doc/manual/rl-next/darwin-daemon-client-pid.md b/doc/manual/rl-next/darwin-daemon-client-pid.md
new file mode 100644
index 000000000..35c0ba375
--- /dev/null
+++ b/doc/manual/rl-next/darwin-daemon-client-pid.md
@@ -0,0 +1,12 @@
+---
+synopsis: "Fetch peer PID for daemon connections on macOS"
+issues: [fj#640]
+cls: [2453]
+category: Fixes
+credits: [lilyball]
+---
+
+`nix-daemon` will now fetch the peer PID for connections on macOS, to match behavior with Linux.
+Besides showing up in the log output line, If `nix-daemon` is given an argument (such as `--daemon`)
+that argument will be overwritten with the peer PID for the forked process that handles the connection,
+which can be used for debugging purposes.
diff --git a/lix/nix/daemon.cc b/lix/nix/daemon.cc
index 4f1437288..2b0bb5155 100644
--- a/lix/nix/daemon.cc
+++ b/lix/nix/daemon.cc
@@ -188,7 +188,13 @@ static PeerInfo getPeerInfo(int remote)
socklen_t credLen = sizeof(cred);
if (getsockopt(remote, SOL_LOCAL, LOCAL_PEERCRED, &cred, &credLen) == -1)
throw SysError("getting peer credentials");
- peer = { false, 0, true, cred.cr_uid, false, 0 };
+ peer = { false, 0, true, cred.cr_uid, true, cred.cr_gid };
+
+#if defined(LOCAL_PEERPID)
+ socklen_t pidLen = sizeof(peer.pid);
+ if (!getsockopt(remote, SOL_LOCAL, LOCAL_PEERPID, &peer.pid, &pidLen))
+ peer.pidKnown = true;
+#endif
#endif
diff --git a/misc/launchd/org.nixos.nix-daemon.plist.in b/misc/launchd/org.nixos.nix-daemon.plist.in
index 664608305..c30dc3505 100644
--- a/misc/launchd/org.nixos.nix-daemon.plist.in
+++ b/misc/launchd/org.nixos.nix-daemon.plist.in
@@ -12,7 +12,7 @@
/bin/sh
-c
- /bin/wait4path /nix/var/nix/profiles/default/bin/nix-daemon && exec /nix/var/nix/profiles/default/bin/nix-daemon
+ /bin/wait4path /nix/var/nix/profiles/default/bin/nix-daemon && exec /nix/var/nix/profiles/default/bin/nix-daemon --daemon
StandardErrorPath
/var/log/nix-daemon.log