macmon – Mac Monitor
macmon is a sudoless performance monitor for Apple Silicon Macs. It reads real-time CPU / GPU / ANE power usage, temperatures, and memory stats through a private macOS API — the same data powermetrics exposes — without requiring root access.
🌟 Features
- 🚫 Runs without sudo
- ⚡ Real-time CPU / GPU / ANE power usage
- 📊 CPU effective usage per cluster
- 💾 RAM / Swap usage
- 📈 Historical charts with average and max values
- 🌡️ Average CPU / GPU temperature
- 🎨 Switchable color themes (6 variants)
- 🪟 Can be displayed in a small window
- 🦀 Written in Rust
📥 Installation
Install using MacPorts:
Install using Cargo:
Install using Nix:
🚀 Usage
)
📚 Library Usage
macmon can be used as a Rust library to collect Apple Silicon metrics in your own applications.
Add it to your project:
Then use the Sampler to collect metrics:
use Sampler;
get_metrics(duration_ms) blocks the calling thread while collecting one
IOReport delta over the complete interval. For a UI, server, or async
application, create the sampler inside a dedicated worker thread and send the
completed metrics back through a channel:
use ;
use Sampler;
Creating Sampler inside the worker keeps its low-level macOS handles on that
thread. In an async runtime, use its blocking-thread facility rather than
calling get_metrics directly from an executor worker.
🚰 Piping
You can use the pipe subcommand to output metrics in JSON format, which makes it suitable for piping into other tools or scripts. For example:
|
This command runs macmon in "pipe" mode and sends the output to jq for pretty-printing.
You can also specify the number of samples to collect using the -s or --samples parameter (default: 0, which runs indefinitely), and set the update interval in milliseconds using the -i or --interval parameter (default: 1000 ms). For example:
|
This will collect 10 samples with an update interval of 500 milliseconds.
{
"timestamp": "2025-02-24T20:38:15.427569+00:00",
"temp": {
"cpu_temp_avg": 43.73614, // Celsius
"gpu_temp_avg": 36.95167, // Celsius
},
"memory": {
"ram_total": 25769803776, // Bytes
"ram_usage": 20985479168, // Bytes
"swap_total": 4294967296, // Bytes
"swap_usage": 2602434560, // Bytes
},
"fans": [
{ "name": "fan0", "rpm": 999, "max_rpm": 4900 },
{ "name": "fan1", "rpm": 1200, "max_rpm": 5200 },
],
"cpu_usage_ratio": 0.036854, // Combined effective CPU usage (frequency-scaled, weighted by core count, 0–1)
"cpu_active_ratio": 0.092, // Combined active residency ratio (not frequency-scaled, weighted by core count, 0–1)
"ecpu_freq_mhz": 1181, // Average frequency while active
"ecpu_usage_ratio": 0.082656614, // Effective usage (frequency-scaled, 0–1)
"ecpu_active_ratio": 0.18, // Active residency (not frequency-scaled, 0–1)
"pcpu_freq_mhz": 1974, // Average frequency while active
"pcpu_usage_ratio": 0.015181795, // Effective usage (frequency-scaled, 0–1)
"pcpu_active_ratio": 0.04, // Active residency (not frequency-scaled, 0–1)
"ecpu_cores": [
{ "die_id": 0, "core_id": 0, "freq_mhz": 1600, "usage_ratio": 0.14, "active_ratio": 0.24 },
{ "die_id": 0, "core_id": 1, "freq_mhz": 1700, "usage_ratio": 0.12, "active_ratio": 0.2 },
],
"pcpu_cores": [
{ "die_id": 0, "core_id": 0, "freq_mhz": 2100, "usage_ratio": 0.05, "active_ratio": 0.08 },
{ "die_id": 0, "core_id": 1, "freq_mhz": 2200, "usage_ratio": 0.07, "active_ratio": 0.06 },
],
"gpu_freq_mhz": 461, // Average frequency while active
"gpu_usage_ratio": 0.021497859, // Effective usage (frequency-scaled, 0–1)
"gpu_active_ratio": 0.09, // GPU active residency ratio (not frequency-scaled, 0–1)
"cpu_power": 0.20486385, // Watts
"gpu_power": 0.017451683, // Watts
"ane_power": 0.0, // Watts
"all_power": 0.22231553, // Watts
"sys_power": 5.876533, // Watts
"ram_power": 0.11635789, // Watts
"gpu_ram_power": 0.0009615385, // Watts (not sure what it means)
}
Deprecated compatibility fields remain available in Rust and serialized JSON:
cpu_usage_pct → cpu_usage_ratio, ecpu_usage →
(ecpu_freq_mhz, ecpu_usage_ratio), pcpu_usage →
(pcpu_freq_mhz, pcpu_usage_ratio), and gpu_usage →
(gpu_freq_mhz, gpu_usage_ratio).
🌐 HTTP Server
You can use the serve subcommand to expose metrics over HTTP. This is useful for integrating with monitoring systems like Prometheus and Grafana.
& # run in background
Two endpoints are available:
| Endpoint | Format | Description |
|---|---|---|
GET /json |
JSON | Current metrics snapshot (same format as pipe --soc-info) |
GET /metrics |
Prometheus | Metrics in Prometheus text format |
Running as a background service (launchd)
To start macmon serve automatically on login and keep it running:
This creates a launchd agent at ~/Library/LaunchAgents/com.macmon.plist that auto-starts on login and restarts on crash.
Prometheus / Grafana setup
Add a scrape target to your prometheus.yml:
scrape_configs:
- job_name: macmon
static_configs:
- targets:
For a ready-to-run local example with Prometheus + Grafana, see example-grafana:
This example provisions:
- Prometheus on
http://localhost:9091 - Grafana on
http://localhost:9000 - a prebuilt
Macmon Overviewdashboard
Grafana login:
- username:
macmon - password:
macmon
Then import or build a Grafana dashboard querying metrics such as:
macmon_cpu_power_watts{chip="Apple M3 Pro"}
macmon_ecpu_usage_ratio{chip="Apple M3 Pro"}
macmon_memory_ram_used_bytes{chip="Apple M3 Pro"}
# HELP macmon_cpu_temp_celsius Average CPU temperature in Celsius
# TYPE macmon_cpu_temp_celsius gauge
macmon_cpu_temp_celsius{chip="Apple M3 Pro"} 47.3
# HELP macmon_cpu_power_watts CPU power consumption in Watts
# TYPE macmon_cpu_power_watts gauge
macmon_cpu_power_watts{chip="Apple M3 Pro"} 8.42
# HELP macmon_fan_speed_rpm Fan speed in revolutions per minute
# TYPE macmon_fan_speed_rpm gauge
macmon_fan_speed_rpm{chip="Apple M3 Pro",fan="fan0"} 1234
# HELP macmon_cpu_usage_ratio Combined CPU effective usage (frequency-scaled, 0–1), weighted by core count
# TYPE macmon_cpu_usage_ratio gauge
macmon_cpu_usage_ratio{chip="Apple M3 Pro"} 0.037
# HELP macmon_cpu_active_ratio Combined CPU active residency ratio (not frequency-scaled, 0–1), weighted by core count
# TYPE macmon_cpu_active_ratio gauge
macmon_cpu_active_ratio{chip="Apple M3 Pro"} 0.092
# HELP macmon_ecpu_usage_ratio Efficiency CPU cluster effective usage (frequency-scaled, 0–1)
# TYPE macmon_ecpu_usage_ratio gauge
macmon_ecpu_usage_ratio{chip="Apple M3 Pro"} 0.083
# HELP macmon_ecpu_active_ratio Efficiency CPU cluster active residency ratio (not frequency-scaled, 0–1)
# TYPE macmon_ecpu_active_ratio gauge
macmon_ecpu_active_ratio{chip="Apple M3 Pro"} 0.18
🧪 Stress Test
Use macmon stress to generate load while checking metric behavior:
The default remains the predictable cyclic CPU load with a fixed 50% duty cycle and 4 CPU workers. Use --full for continuous CPU and GPU load; when --workers is omitted, full mode uses all logical CPUs.
🤝 Contributing
All contributions are welcome! Feel free to open an issue or submit a pull request.
📝 License
Distributed under the MIT License.
🔍 See also
- tlkh/asitop – The original tool. Written in Python, requires sudo.
- dehydratedpotato/socpowerbud – Written in Objective-C, sudoless, no TUI.
- op06072/NeoAsitop – Written in Swift, sudoless.
- graelo/pumas – Written in Rust, requires sudo.
- context-labs/mactop – Written in Go, requires sudo.