Skip to content

Add nix ps command#15979

Open
edolstra wants to merge 5 commits into
masterfrom
nix-ps
Open

Add nix ps command#15979
edolstra wants to merge 5 commits into
masterfrom
nix-ps

Conversation

@edolstra

@edolstra edolstra commented Jun 5, 2026

Copy link
Copy Markdown
Member

Motivation

nix ps shows active builds, e.g.

USER      PID         CPU  DERIVATION/COMMAND
nixbld11  3534394  110.2s  /nix/store/lzvdxlbr6xjd9w8py4nd2y2nnqb9gz7p-nix-util-tests-3.13.2.drv (wall=8s)
nixbld11  3534394    0.8s  └───bash -e /nix/store/vj1c3wf9c11a0qs6p3ymfvrnsdgsdcbq-source-stdenv.sh /nix/store/shkw4qm9qcw5sc5n1k5jznc83ny02
nixbld11  3534751   36.3s      └───ninja -j24
nixbld11  3535637    0.0s          ├───/nix/store/8adzgnxs3s0pbj22qhk9zjxi1fqmz3xv-gcc-14.3.0/bin/g++ -fPIC -fstack-clash-protection -O2 -U_
nixbld11  3535639    0.1s          │   └───/nix/store/8adzgnxs3s0pbj22qhk9zjxi1fqmz3xv-gcc-14.3.0/libexec/gcc/x86_64-unknown-linux-gnu/14.3.
nixbld11  3535658    0.0s          └───/nix/store/8adzgnxs3s0pbj22qhk9zjxi1fqmz3xv-gcc-14.3.0/bin/g++ -fPIC -fstack-clash-protection -O2 -U_
nixbld1   3534377    1.8s  /nix/store/nh2dx9cqcy9lw4d4rvd0dbsflwdsbzdy-patchelf-0.18.0.drv (wall=5s)
nixbld1   3534377    1.8s  └───bash -e /nix/store/v6x3cs394jgqfbi0a42pam708flxaphh-default-builder.sh
nixbld1   3535074    0.0s      └───/nix/store/0irlcqx2n3qm6b1pc9rsd2i8qpvcccaj-bash-5.2p37/bin/bash ./configure --disable-dependency-trackin

This improves the observability of a Nix system.

It's implemented by having Nix keep track of the root PIDs of active builds in /nix/var/nix/active-builds/ and adding a daemon protocol operation for querying active builds and their CPU stats (so this also works over ssh-ng stores).

Taken from Determinate Nix (mostly DeterminateSystems#282).

Context


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

edolstra and others added 4 commits June 4, 2026 20:48
Tables now hold `TableCell` values (content + alignment) instead of bare
strings, and `printTable()` accepts a max width that truncates lines via
`filterANSIEscapes`. The implicit `TableCell(std::string)` constructor
keeps existing callers working; `nix-env --query` is updated to use the
new `TableRow` alias.

This prepares the table utility for `nix ps`, which needs right-aligned
numeric columns and terminal-width-aware output.
Returns the terminal's column count, or `numeric_limits<unsigned int>::max()`
when unknown. Lets callers ask for a usable width directly instead of
unpacking `getWindowSize()` and special-casing zero.
Adds a new `nix ps` command that lists active builds along with their
process trees and CPU usage. This is upstreamed from Determinate Nix.

The implementation:

* `ActiveBuild` / `ActiveBuildInfo` describe a running build; `LocalStore`
  persists one JSON file per active build under
  `$NIX_STATE_DIR/active-builds`, holding a write lock to denote liveness.
  `DerivationBuilderImpl` registers/unregisters via an RAII `BuildHandle`.
* `QueryActiveBuildsStore` is a new store mixin; `LocalStore` walks
  `active-builds/` and enriches each entry with per-process info from
  `/proc` (Linux) or `proc_pidinfo`/`sysctl` (macOS), and cgroup CPU
  stats when a cgroup is available.
* `RemoteStore` proxies the query over a new
  `WorkerProto::Op::QueryActiveBuilds` (op 48), gated on the
  `queryActiveBuilds` feature flag.
* New `getPidsInCgroup()` helper enumerates the PIDs in a cgroup.
* `nix ps` renders a tree-formatted table with right-aligned CPU column,
  truncated to terminal width on a TTY. `--json` emits the raw
  `ActiveBuildInfo` array.
Starts a build that backgrounds a `sleep 600` and blocks on a fifo,
then asserts that `nix ps` (text and `--json`) reports the running
derivation and its two-level process tree (builder shell + sleep
child), and that the list becomes empty once the build finishes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@edolstra
edolstra requested a review from Ericson2314 as a code owner June 5, 2026 08:46
@github-actions github-actions Bot added documentation new-cli Relating to the "nix" command with-tests Issues related to testing. PRs with tests have some priority store Issues and pull requests concerning the Nix store labels Jun 5, 2026
@lisanna-dettwyler

lisanna-dettwyler commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Would it be much work to add memory usage? The biggest issue I have with mass nixpkgs rebuilds isn't CPU but running out of memory, observability into that would be awesome especially for downstream tools that could consume it and process it, e.g., determine the maximum memory per CPU usage of a derivation for resource management purposes.

Edit: Actually, I can work on this, I'll put up a PR against this branch when it's working.

@lisanna-dettwyler

Copy link
Copy Markdown
Contributor

When run in sudo mode and there are ongoing builds, it'll hang on "waiting for exclusive access to the Nix store" (but you have to use -v to see that).

andrewgazelka added a commit to indexable-inc/index that referenced this pull request Jul 7, 2026
…fix to catch (BaseError&) (#2021)

Follow-through on the stopped NixOS/nix upstreaming wave.

## What changed

**`lib/fork-packages.nix` — nix `upstreamPolicy`**
- `aiPrsAllowed = "false"`, citing
[NixOS/nix#15984](NixOS/nix#15984) and its three
operative constraints: human-authored PR communication, no unreviewed
automated submissions, `Assisted-by:` disclosure trailer.
`upstream-sync` now refuses to open any nix PR at the repo level.

**Patch intent — all nix patches flipped `attempt` → `hold`**
- `0001` (GC-roots daemon crash): reworked to `catch (BaseError&)` (the
narrowing proposed in [#15963](NixOS/nix#15963)
after xokdvium objected to `catch (...)`); a human resubmits.
- `0002` (lookup-path EPERM eval fix): cleanest candidate, framed as
restoring the EPERM-tolerant path probing of
[#8240](NixOS/nix#8240) lost in the
`std::filesystem` migration (see #5884, still-open #8485); a human
submits.
- `0003-0009` (build-status series): engage on edolstra's active
[#15979](NixOS/nix#15979) (`nix ps`) instead of
filing a competing series.

**Patch rework + disclosure**
- `packages/nix/nix/patches/0001` reworked (`catch (BaseError&)`,
concise comment addressing xokdvium's "too verbose" note).
- `Assisted-by: Claude <noreply@anthropic.com>` trailers added to `0001`
and `0002` commit messages, regenerated deterministically via `git
format-patch --zero-commit --no-signature --no-stat -N`. Build-status
series bytes unchanged.
- `upstream-status.json` regenerated (`nix run .#upstream-sync -- nix`):
all nine now `hold`.

**Incidental unblock**
- `packages/nu-py/python/nu/__init__.py`: `os.getcwd()` → `Path.cwd()` —
a pre-existing ruff PTH109 failure on main (from #1999) that blocked the
pre-commit lint for every subsequent commit.

## Validation
- `checks.aarch64-darwin.patched-src-nix` — green (all 9 patches apply,
incl. reworked 0001).
- `checks.aarch64-darwin.patch-dag-nix` — `OK (9 patches, 0 edges)`.
- `nix run .#upstream-sync -- nix --dry-run` — plans **nothing**
outward: all 9 patches `[skip]`, repo-level block reported, no
`would-open`/`attempt-ready`.
- Full `nix-ix` package build (validates the reworked C++ compiles) —
running.

## Machinery gaps filed as issues
- #2016 — semantic duplicate detection (title-token search missed #15979
vs our build-status subjects).
- #2017 — series grouping (empty DAG deps ⇒ closure grouping never
engages).
- #2018 — `Assisted-by` commit-trailer support as policy-driven
disclosure.

## Human handoff
Ready-to-send PR drafts (0001, 0002) and the #15979 comment are in
`~/Projects/indexable-inc/nix-upstream-handoff.html` for Andrew as the
accountable submitter. **No PRs are filed on NixOS/nix by this change**
— the kit is for a human to submit.

Prepared with AI assistance (Claude); directed and reviewed by a human
maintainer.


<!-- Macroscope's pull request summary starts here -->
<!-- Macroscope will only edit the content between these invisible
markers, and the markers themselves will not be visible in the GitHub
rendered markdown. -->
<!-- If you delete either of the start / end markers from your PR's
description, Macroscope will append its summary at the bottom of the
description. -->
> [!NOTE]
> ### Hold all NixOS/nix upstreaming and rework GC-roots patch to catch
`BaseError&`
> - Sets `aiPrsAllowed` to `false` in the upstream policy for NixOS/nix,
blocking automated PR creation against that repo per
[NixOS/nix#15984](NixOS/nix#15984).
> - Changes all nine patch entries in
[fork-packages.nix](https://github.com/indexable-inc/index/pull/2021/files#diff-35e5ff5b02c2dcd32c93fd770ad2194f9fcbfc9f35fdcbd56821891b6e7452f4)
and
[upstream-status.json](https://github.com/indexable-inc/index/pull/2021/files#diff-9407ed440a363a47ae2dbcca49731c8db3d7dfe38943d75473dd0f5c4fec28eb)
from `attempt` to `hold`, deferring upstreaming to humans.
> - Reworks
[0001-fix-libstore-don-t-crash-the-daemon-when-a-GC-roots-.patch](https://github.com/indexable-inc/index/pull/2021/files#diff-2a703db65303f7f7d269ae802072e8f5e4a984d141b3ab175452f2051dd5d197)
to catch `BaseError&` instead of `Error&`, so `Interrupted` exceptions
no longer escape the GC client-root thread and crash the daemon; removes
the earlier blanket `catch(...)` block.
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized
00a7768.</sup>
> <!-- Macroscope's review summary ends here -->
>
<!-- macroscope-ui-refresh -->
<!-- Macroscope's pull request summary ends here -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation new-cli Relating to the "nix" command store Issues and pull requests concerning the Nix store with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants