← All writings

Per-Process Network Stats on macOS with NetworkStatistics.framework

Abstract network of connected nodes, representing per-process network statistics

Ever wondered how nettop on macOS knows exactly how many bytes each process has sent? There is no public API for it — Apple keeps the machinery in a private framework called NetworkStatistics.framework.

Digging into nettop

Running otool -L on the nettop binary shows it links against the private framework. From there it's a matter of class-dumping the headers and figuring out which functions give you per-process counters.

extern int nstat_provider_create(int provider);
extern int nstat_provider_add_all_tcp_conns(int provider);

The framework exposes a provider/source model: you create a provider, subscribe to sources (TCP connections, UDP endpoints, routes), and poll for updates.

Building the tool

With the function signatures in hand, a small C program can print per-process byte counts:

nstat_msg_src_counts counts;
if (nstat_get_counts(fd, &counts) == 0) {
  printf("%llu bytes in, %llu bytes out\n",
         counts.rxbytes, counts.txbytes);
}

Private frameworks can change or vanish in any macOS release. This is a learning exercise, not something to ship.

The result is a tiny Prometheus exporter that scrapes these counters on an interval — a fun way to watch which of your processes are chatty.