---
title: "Prometheus — rate(joules_total) Already Returns Watts"
aliases: [prometheus-watts, prometheus-joules, promql-power-metrics, grafana-power-dashboard]
tags: [prometheus, promql, grafana, metrics, power, homelab, monitoring]
sources:
  - "daily/2026-04-21.md"
created: 2026-04-21
updated: 2026-04-21
---

# Prometheus — rate(joules_total) Already Returns Watts

When calculating power consumption from Prometheus energy counters, `rate(joules_total[interval])` already produces the result in **watts** (joules per second). Multiplying this by 1000 converts watts to milliwatts — not to kilowatts as developers sometimes assume — causing a 1000× display error in Grafana dashboards where values show as kilowatts instead of watts.

## Key Points

- **`rate(joules_total[1m])` returns watts** — rate of joules per second = watts (by definition: 1 W = 1 J/s)
- **Do not multiply by 1000** — this gives milliwatts disguised as kilowatts (both wrong units for typical server power readings)
- The bug manifests as: Grafana dashboard shows "2500 W" when the server is actually drawing 2.5 W, or shows "250 W" when actual draw is 0.25 W
- Correct PromQL for watts: `rate(node_cpu_seconds_total{mode!="idle"}[1m])` style or directly `rate(rapl_package_joules_total[1m])`
- Always spot-check power readings against a physical power meter or known consumption baseline — 2500 W is implausible for an idle homelab server

## Details

### The Physics

Power (watts) = Energy (joules) ÷ Time (seconds)

Prometheus `rate()` computes the per-second rate of a counter, so:

```
rate(joules_total[1m]) = Δjoules / Δseconds = watts
```

This is mathematically identical to the definition of a watt. No conversion factor is needed.

### Common Node Exporter Metrics for Power

```promql
# Package power (Intel RAPL or AMD RAPL-equivalent) — result in watts
rate(node_rapl_package_joules_total[1m])

# DRAM power
rate(node_rapl_dram_joules_total[1m])

# Total server power (if using a PDU or smart plug exporter)
rate(smart_plug_energy_joules_total[1m])
```

All of these return watts without any multiplication.

### The Bug Pattern

```promql
# WRONG — produces milliwatts (labeled as W, appears as kW)
rate(rapl_package_joules_total[1m]) * 1000

# CORRECT — watts
rate(rapl_package_joules_total[1m])
```

A developer sees the raw joule values (large counter numbers), assumes `rate()` returns joules/minute, and multiplies by 1000 to "convert to watts". But `rate()` always normalizes to per-second, so the output is already watts.

### Grafana Dashboard Fix

In the Grafana panel editor:
1. Remove the `* 1000` from the PromQL expression
2. Verify the unit in **Standard options → Unit** is set to `Watt (W)`, not `kilowatt (kW)`
3. Check the Y-axis maximum — if it was set based on the wrong scale (e.g., 3000 for "3000 W"), adjust to a realistic maximum

### Sanity Check Values

Typical homelab server power consumption:
- Idle, low-spec (N100, small board): 8–20 W
- Idle, mid-range (Ryzen 5, full tower): 30–80 W
- Idle, server-grade (Xeon, IPMI): 80–150 W
- Full load (gaming GPU active): 200–400 W

If Grafana shows a homelab server consuming 2500 W idle, the metric is wrong.

## Related Concepts

- [[wiki/concepts/old-gpu-sysfs-metrics]] — related Grafana/Prometheus metrics topic for GPU utilization on older hardware
- [[wiki/concepts/beszel-monitoring-deployment]] — Beszel as a monitoring alternative to Prometheus for simpler homelab setups
- [[wiki/homelab/_index]] — homelab Grafana/Prometheus stack context

## Sources

- [[daily/2026-04-21.md]] — Grafana Power & Cost dashboard showing watts as kilowatts; root cause was `* 1000` in PromQL where `rate(joules_total)` already returns watts; fixed by removing the multiplier
