
A Mac running your team's local models is also an ordinary computer. Its disk fills up. A background job competes for memory. A machine that was quiet yesterday runs hot today. When a workflow slows down, you need a history of the machine's condition alongside the application's own logs.
Pulseki is our open-source macOS metrics exporter. It collects system measurements and makes them available to Prometheus, or pushes them to an OpenTelemetry endpoint. You choose where to store the history and how to display it. The exporter runs on the Mac; a cloud monitoring account is optional.
What Pulseki measures
Pulseki uses native macOS interfaces through Swift and a small C layer. The current Homebrew release requires macOS 13 or later and builds with Apple's Command Line Tools. It has no third-party package dependencies.
| Area | What you can follow |
|---|---|
| CPU and load | Time spent working or idle, system load, and performance/efficiency core topology |
| Memory | Free, active, wired, and compressed memory, swap use, and macOS memory pressure |
| GPU | Driver-reported utilization and memory, available GPU information, and recovery counts |
| Storage and network | Filesystem capacity, disk reads/writes, and interface traffic and errors |
| Temperature and power | macOS thermal state, available SMC temperature/power sensors, and fan speeds |
| Battery and system | Charge and battery health on portables, uptime, OS version, and hardware identity |
Availability depends on the hardware and the interfaces macOS exposes. Pulseki uses familiar node_ metric names where their meanings match node_exporter, and macos_ names for Mac-specific measurements. That helps reuse existing queries, but Linux-only dashboard panels will still be empty. See the metrics reference for exact names and units.
Pulseki also measures its own collectors and push requests. A missing sensor reading should lead you to collector health and the error log, rather than an assumption that the hardware is idle.
A concrete use: investigating a slow local model
Imagine a Mac Studio handling document processing and model inference. Requests take longer when a second workload starts. Pulseki gives you several things to compare over the same time window:
- Memory pressure and swap: did pressure rise or swapping increase as the workload changed?
- GPU utilization: was the accelerator busy, or was the application waiting elsewhere?
- Thermal state: did macOS report a more constrained thermal condition?
- Disk and network activity: did loading files or moving data coincide with the slowdown?
These are diagnostic clues. GPU utilization is not tokens per second, thermal state is not a measured clock speed, and system metrics cannot tell you whether a model's answer was correct. Pair them with application latency, throughput, and task-quality measurements. The useful result is a narrower investigation and a record you can compare with the next change.
Start with one Mac
Install the released exporter:
brew install looskis/tap/pulseki
Before starting the service, edit $(brew --prefix)/etc/pulseki.conf. For an initial check on the same Mac, set:
listen = 127.0.0.1:9101
path = /metrics
Then start it and inspect the output:
brew services start pulseki
curl --fail http://127.0.0.1:9101/metrics
Look for pulseki_build_info and pulseki_scrape_collector_success, along with the system measurements. This service starts at login. An always-on Mac can instead use sudo brew services start pulseki to start at boot, before login; the exporter itself does not require root. See the configuration reference before changing how an existing service runs.
The shipped default listens on all interfaces at 0.0.0.0:9101 and has no built-in authentication. Choose the listener deliberately. Loopback is appropriate for a local collector or outbound push; a remote Prometheus needs a reachable, protected address, such as the Mac's Tailscale address with access restricted to the monitoring host.
Choose where the measurements go
There are two collection paths. Both expose the same system measurements, and the HTTP endpoint remains available when push is enabled.
| Path | How it works | A useful fit |
|---|---|---|
| Prometheus pull | A Prometheus server requests /metrics at an interval and stores the samples. | Always-on Macs reachable from a central monitoring host |
| OTLP push | Pulseki sends metrics to a configured OTLP/HTTP endpoint. | Macs that cannot accept inbound scrapes, including roaming laptops |
For Prometheus running on the same Mac, this scrape configuration matches the loopback listener above:
scrape_configs:
- job_name: macos
scrape_interval: 15s
static_configs:
- targets: ["127.0.0.1:9101"]
For a remote server, replace that target with the protected address you configured on the Mac. Loopback always means the machine running Prometheus.
For push, configure push.url, the endpoint's credentials when required, and a stable push.instance name in pulseki.conf, then restart the service. The push setup guide explains Grafana Cloud's OTLP endpoint and token-file configuration. A self-hosted OpenTelemetry collector is another option. Keep credentials in a protected file rather than command-line arguments.
Push is off by default. Enabling a cloud destination sends the collected metrics and host labels there, so the monitoring data follows that provider's boundary. For an entirely on-premises arrangement, keep the collector, storage, and dashboard on premises too.
From one machine to a fleet
The fleet guide describes central Prometheus collection over Tailscale, including target discovery and access rules. Always-on Macs can be scraped centrally while laptops push when online. If the central server already forwards a Mac's metrics to the same cloud store, do not also enable direct push for that Mac: you would submit the same measurements twice.
The repository includes a Grafana dashboard with an Instance selector and sections for the machine and exporter health. The dashboard import script uses Grafana's API to load or update it. These dashboard assets were added after the v0.1.0 tag; get them from the repository rather than expecting Homebrew to install them with the binary.
Pulseki supplies the measurements. Prometheus or your chosen backend retains history; Grafana displays it; alert rules belong in your monitoring stack. Choose alert thresholds and durations from the workload you actually run.
Limits to understand before relying on it
Sensor coverage varies across Macs. GPU frequency and GPU power from the private IOReport framework are not included. SMC power readings are a separate source and should not be relabeled as a GPU-power measurement.
Push has no durable local queue. If the destination is unavailable, the missing interval leaves a gap rather than being replayed later. Sleeping and offline machines cannot provide continuous samples. Monitor push success as well as the computer's health.
Pulseki is useful when you want to understand the machines behind your workflows: whether capacity is tight, whether conditions changed, and where to investigate next. Start with one Mac, collect a representative period of normal work, and build your dashboard around questions you need to answer.
Get Pulseki on GitHub, or explore the rest of the Looskis tools.
Frequently asked questions
Does Pulseki require Grafana Cloud?
No. You can scrape it with a local Prometheus server and keep monitoring on premises. OTLP push is optional and can target a self-hosted collector or a cloud endpoint.
Does Pulseki measure model quality or inference speed?
It measures the Mac, including CPU, GPU, memory, storage, and thermal conditions. Measure application latency, tokens per second, and task quality separately, then compare those results with the system metrics.
Does it need root or an administrator account to collect metrics?
The exporter does not need root. The documented sudo brew services command is an alternative for registering startup at boot, before login; ordinary brew services start runs it at login.
Can I use the existing Node Exporter Full dashboard?
Pulseki uses node_exporter-compatible names where the semantics match, so some existing panels and queries are reusable. Linux-only panels stay empty. The Pulseki repository also provides a dashboard for its Mac-specific metrics.
What happens if a push destination goes offline?
Pulseki exposes push-health metrics and logs failures, but has no durable local queue. Missed intervals are gaps in the history; they are not replayed after the destination recovers.