nod#
A daemon that collects Nix build and substitution statistics using structured JSON logs.
requirements#
- Nix 2.30 or later (
json-log-pathsupport)
building#
cargo build --release
usage#
Start the daemon:
nod daemon
Point Nix at the socket in nix.conf:
json-log-path = /tmp/nod.sock
Then use Nix normally. Query accumulated stats:
nod # aggregate stats, all time
nod -d 30 # last 30 days
nod -m 3 # last 3 months
nod --drv firefox # filter to derivations matching "firefox"
nod --sort count --group # group by derivation, sort by frequency
nod --bucket day # time series by day
nod --bucket month # time series by month
nod --bucket day --output test # Mann-Whitney significance test vs prior period
nod --bucket day --output csv # CSV output
nod clean # delete all events
nod clean --before-days 90 # delete events older than 90 days
NixOS#
{
services.nod = {
enable = true;
retainDays = 180; # default
};
}
The module sets nix.settings.json-log-path automatically and exports NOD_SOCKET into /etc/environment so every session (login, SSH, scripts) finds the daemon without --socket.
configuration#
| flag | env | default |
|---|---|---|
--socket |
NOD_SOCKET |
/tmp/nod.sock |
--db |
NOD_DB |
nod.db (current directory) |
When using the NixOS module both are pinned to fixed system paths and exported automatically.
how?#
Nix 2.30 added json-log-path, which writes a stream of structured activity events (start/result/stop) to a file or Unix socket while a build runs. nod listens on that socket, tracks in-flight activities by ID, and on each stop event inserts a completed row into a local SQLite database. nod queries that database through the daemon socket.
Stats queries are served from a pre-aggregated daily_stats table (one row per day per event type) maintained in lockstep with inserts, so summary queries are O(days) regardless of total event count. The current day's aggregates are held in memory and flushed on day rollover.
Relevant Nix source: logging.hh