Skip to content

fix(agent): round load average to two decimals - #2245

Merged
henrygd merged 1 commit into
henrygd:mainfrom
justadityaraj:fix/round-load-average
Aug 21, 2026
Merged

henrygd merged 1 commit into
henrygd:mainfrom
justadityaraj:fix/round-load-average

Conversation

@justadityaraj

Copy link
Copy Markdown
Contributor

📃 Description

Fixes #2071.

getSystemStats stores every metric through utils.TwoDecimals, except the load averages, which were assigned straight from gopsutil:

systemStats.Cpu = utils.TwoDecimals(cpuMetrics.Total)
systemStats.CpuBreakdown = []float64{utils.TwoDecimals(cpuMetrics.User), ...}
...
systemStats.LoadAvg[0] = avgstat.Load1   // not rounded

Linux hides this because /proc/loadavg is already two decimal places. Other platforms are not so tidy:

  • Windows has no real load average, so gopsutil synthesises one as a decaying EWMA over the \System\Processor Queue Length counter. It approaches zero without reaching it, which is where the reporter's 1.3667392689044936e-73 comes from. The value is not wrong, it is just never rounded.
  • macOS and BSD divide a fixed point value by fscale, giving numbers like 2.55322265625.

The hub already treats two decimals as the canonical precision here, since records.go rounds the load average when averaging records. That left the raw agent records as the only place carrying full precision.

So this is not really Windows specific, it is every platform whose load average does not arrive pre-rounded. Windows is just where it looks alarming.

🪵 Changelog

🔧 Fixed

  • Load average is now rounded to two decimals, consistent with every other metric the agent reports.

Steps to verify the change

I do not have a Windows box, so I verified on macOS, which has the same unrounded behaviour for the same reason.

Built a small probe from this module calling the same load.Avg() the agent calls, cross compiled for darwin/arm64, and ran it natively:

before_la: [2.55322265625, 2.7646484375, 2.90234375]
after_la:  [2.55, 2.76, 2.90]

uptime on the same machine at the same moment:

load averages: 2.55 2.76 2.90

Also ran:

  • go test -tags="testing no_ui" ./agent/... — all green, unchanged from before the patch
  • gofmt -l agent/system.go — clean
  • go vet ./agent/ — clean
  • Cross compiled ./internal/cmd/agent for windows/amd64, linux/amd64, darwin/arm64 and freebsd/amd64

One thing I checked because it looked like a risk: rounding means a genuinely idle Windows host now reports exactly [0, 0, 0], which is close to #982. It does not come back. The la field is cbor:"28,keyasint" with no omitempty, and json:"la,omitempty" is a no-op on a [3]float64, so the array still serialises.

No test added. getSystemStats calls load.Avg() directly with no seam to inject a value, and utils.TwoDecimals already has its own tests, so a test here would either need a refactor larger than the fix or would only re-test the helper.

Type

  • Fix

Checklist

  • Title follows the conventional commit format
  • Tested locally
  • I have no unrelated changes in the PR

Every other metric in getSystemStats is stored through utils.TwoDecimals.
The load averages were assigned straight from gopsutil, so whatever the
platform reported was recorded verbatim.

On Linux that goes unnoticed because /proc/loadavg is already two decimal
places. Everywhere else it is not. macOS and BSD divide a fixed point
value by fscale and produce numbers like 2.55322265625, and the Windows
implementation synthesises the average as a decaying EWMA over the
processor queue length counter, so an idle machine reports values like
1.3667392689044936e-73 instead of 0.

The hub already treats two decimals as the canonical precision for this
field, since records.go rounds the load average when it averages records.
That left the raw agent records as the only place carrying full precision.
@justadityaraj
justadityaraj requested a review from henrygd as a code owner August 19, 2026 22:15

@henrygd henrygd left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Didn't know that was happening.

@henrygd
henrygd merged commit f1e5797 into henrygd:main Aug 21, 2026
@justadityaraj

Copy link
Copy Markdown
Contributor Author

Anytime man, love beszel, would contribute as much as I can <3

JuliusFreudenberger pushed a commit to JuliusFreudenberger/nix-config that referenced this pull request Sep 3, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [henrygd/beszel](https://github.com/henrygd/beszel) | minor | `0.18.8` → `0.19.0` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/12) for more information.

---

### Release Notes

<details>
<summary>henrygd/beszel (henrygd/beszel)</summary>

### [`v0.19.0`](https://github.com/henrygd/beszel/releases/tag/v0.19.0)

[Compare Source](henrygd/beszel@v0.18.8...v0.19.0)

:warning:  **Potential breaking change:** Agents now verify HTTPS certificates. If an agent connects to a hub using a self-signed or otherwise untrusted certificate, configure `CA_CERT_FILE` with the appropriate CA certificate or the connection will be rejected.

#### What's Changed

- Add ZFS pool and dataset monitoring ([#&#8203;2209](henrygd/beszel#2209))
- Add container health alerts with log excerpts in notifications ([#&#8203;2225](henrygd/beszel#2225))
- Add alerts for failed systemd services ([#&#8203;2173](henrygd/beszel#2173))
- Add alerts for CPU I/O wait and steal time ([#&#8203;2249](henrygd/beszel#2249))
- Add cumulative disk read and write totals to the Disk I/O sheet ([#&#8203;2179](henrygd/beszel#2179))
- Add Greek and Uzbek translations ([#&#8203;2034](henrygd/beszel#2034))
- Add custom root disk names and sort disks alphabetically ([#&#8203;2006](henrygd/beszel#2006))
- Improve alert security by enforcing system ownership and blocking additional internal notification URL ranges
- Improve ATA SMART warnings for critical attributes ([#&#8203;2275](henrygd/beszel#2275))
- Fix a hub crash caused by concurrent SSH client shutdown ([#&#8203;2277](henrygd/beszel#2277))
- Fix host CPU and memory totals when Docker runs in a VM on macOS or Windows ([#&#8203;2272](henrygd/beszel#2272))
- Fix multi-line `TOKEN_FILE` loading ([#&#8203;2276](henrygd/beszel#2276))
- Fix QNAP MD RAID arrays being incorrectly reported as failed ([#&#8203;2065](henrygd/beszel#2065))
- Fix Intel GPU power data disappearing between samples ([#&#8203;2256](henrygd/beszel#2256))
- Fix swap usage calculations to include cached swap ([#&#8203;2267](henrygd/beszel#2267))
- Fix agent payload failures caused by invalid UTF-8 in battery names ([#&#8203;2241](henrygd/beszel#2241))
- Fix uptime reporting inside Linux containers ([#&#8203;2180](henrygd/beszel#2180))
- Fix fan discovery on legacy hwmon devices ([#&#8203;2238](henrygd/beszel#2238))
- Fix CPU model detection on MIPS systems ([#&#8203;2138](henrygd/beszel#2138))
- Fix machine ID generation on FreeBSD and pfSense installations ([#&#8203;2274](henrygd/beszel#2274))
- Fix agent environment variable updates during reinstall ([#&#8203;2107](henrygd/beszel#2107))
- Fix the install script reporting the wrong listen address after upgrades ([#&#8203;2243](henrygd/beszel#2243))
- Fix load average precision on macOS, BSD, and Windows ([#&#8203;2245](henrygd/beszel#2245))
- Update the Go version and Go dependencies

#### New Contributors

- [@&#8203;IlyaMur](https://github.com/IlyaMur) made their first contribution in [#&#8203;2238](henrygd/beszel#2238)
- [@&#8203;alecrubin](https://github.com/alecrubin) made their first contribution in [#&#8203;2180](henrygd/beszel#2180)
- [@&#8203;toomore](https://github.com/toomore) made their first contribution in [#&#8203;2241](henrygd/beszel#2241)
- [@&#8203;mews-se](https://github.com/mews-se) made their first contribution in [#&#8203;2243](henrygd/beszel#2243)
- [@&#8203;justadityaraj](https://github.com/justadityaraj) made their first contribution in [#&#8203;2245](henrygd/beszel#2245)
- [@&#8203;wassupluke](https://github.com/wassupluke) made their first contribution in [#&#8203;2256](henrygd/beszel#2256)
- [@&#8203;ErkinjonYusupov](https://github.com/ErkinjonYusupov) made their first contribution in [#&#8203;2034](henrygd/beszel#2034)
- [@&#8203;snh](https://github.com/snh) made their first contribution in [#&#8203;2279](henrygd/beszel#2279)
- [@&#8203;spatiumstas](https://github.com/spatiumstas) made their first contribution in [#&#8203;2249](henrygd/beszel#2249)
- [@&#8203;martinstenrose](https://github.com/martinstenrose) made their first contribution in [#&#8203;2173](henrygd/beszel#2173)
- [@&#8203;mleczakm](https://github.com/mleczakm) made their first contribution in [#&#8203;2225](henrygd/beszel#2225)
- [@&#8203;santhiprakash](https://github.com/santhiprakash) made their first contribution in [#&#8203;2269](henrygd/beszel#2269)

**Full Changelog**: <henrygd/beszel@v0.18.8...v0.19.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTAuMSIsInVwZGF0ZWRJblZlciI6IjQzLjE1MC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://git.jfreudenberger.de/JuliusFreudenberger/nix-config/pulls/43
xiaoran7 pushed a commit to xiaoran7/beszel that referenced this pull request Oct 17, 2026
Every other metric in getSystemStats is stored through utils.TwoDecimals.
The load averages were assigned straight from gopsutil, so whatever the
platform reported was recorded verbatim.

On Linux that goes unnoticed because /proc/loadavg is already two decimal
places. Everywhere else it is not. macOS and BSD divide a fixed point
value by fscale and produce numbers like 2.55322265625, and the Windows
implementation synthesises the average as a decaying EWMA over the
processor queue length counter, so an idle machine reports values like
1.3667392689044936e-73 instead of 0.

The hub already treats two decimals as the canonical precision for this
field, since records.go rounds the load average when it averages records.
That left the raw agent records as the only place carrying full precision.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: [Windows] Abnormal Load Average values returned

2 participants