Five Impossible Values I Found in Real Windows Battery Reports
Windows can export a detailed battery report with one command: powercfg /batteryreport The resulting battery-report.html looks like clean, structured data. I built a browser-based reader for it, so I assumed par
Windows can export a detailed battery report with one command:
powercfg /batteryreport
The resulting battery-report.html looks like clean, structured data. I built a browser-based reader for it, so I assumed parsing would be the easy part. Then I ran it against real reports from four laptops and found values that are flat-out impossible.
This post covers what those values looked like and the sanity checks I now run before trusting any number from the file.
The four reports
| Laptop | Design | Full charge | Health | Cycle count |
|---|---|---|---|---|
| Lenovo 82TS (~2 years) | 45,000 mWh | 42,650 mWh | 94.8% | 141 |
| HP ZBook Firefly 14 G7 | 53,015 mWh | 39,189 mWh | 73.9% | 454 |
| ThinkPad (~10 years) | 47,520 mWh | 27,380 mWh | 57.6% | - |
| ThinkPad (4–5 years use) | 99,470 mWh | 24,800 mWh | 24.9% | - |
Health is just FullChargeCapacity / DesignCapacity * 100. The interesting part is everything around it.
Problem 1: a row that is 3× too big
One ThinkPad's Battery capacity history table had this row:
2026-10-30 27,380 mWh 47,520 mWh
2026-10-31 83,235 mWh 144,460 mWh <- ???
2026-11-01 27,380 mWh 47,520 mWh
The ratio is still 57.6%, so a naive health calculation looks fine. But if you chart full charge capacity over time, you get a spike that suggests the battery tripled overnight.
Check: design capacity should be constant for a given battery. If a row's design value differs from the median design value by more than a few percent, flag the whole row.
function flagDesignOutliers(rows) {
const designs = rows.map(r => r.design).sort((a, b) => a - b);
const median = designs[Math.floor(designs.length / 2)];
return rows.map(r => ({
...r,
suspect: Math.abs(r.design - median) / median > 0.05
}));
}
Problem 2: 67 years of AC time in one week
The Lenovo's Usage history section listed an AC duration of 592618:40:06 for a single week. That's about 67 years.
Check: a period can't contain more hours than it spans. Parse the period start and end, compute the maximum possible duration, and reject anything above it.
function hmsToHours(s) {
const [h, m, sec] = s.split(':').map(Number);
return h + m / 60 + sec / 3600;
}
function isPlausibleDuration(hms, periodStart, periodEnd) {
const maxHours = (periodEnd - periodStart) / 3.6e6;
return hmsToHours(hms) <= maxHours + 1; // 1 h slack for DST and boundaries
}
Problem 3: standby drains over 100% per 16 hours
Laptops with Modern Standby show a connected-standby drain rate like 39 % / 16 h. Across a few weeks, the same Lenovo reported 1 % / 16 h (a 1,929-hour estimate) and 994 % / 16 h. The HP hit 1,061 % / 16 h.
A drain above 100% in 16 hours isn't strictly impossible, but these values swing so wildly week to week that I treat them as noise unless several weeks agree.
Check: show the median across weeks, and label single extreme weeks instead of averaging them in.
Problem 4: the cycle count is a dash
Both ThinkPads report CYCLE COUNT -. It's not zero and not a parsing bug. The firmware simply doesn't expose it to Windows.
Check: treat -, empty, and 0 as "not reported" and say so in the UI. Displaying 0 cycles for a 10-year-old battery is wrong and erodes trust in every other number on the screen.
function parseCycleCount(raw) {
const n = Number(String(raw).replace(/[^\d]/g, ''));
return Number.isFinite(n) && n > 0 ? n : null; // null = not reported
}
Problem 5: a single reading can be far off
Even when every row is plausible, one reading can mislead. The older ThinkPad reported 3% health for five months, then about 25% from late September, with nothing done to the battery. The other ThinkPad jumped from 46% to 57.6% in the same few weeks. The most likely cause is the battery's fuel gauge correcting its own estimate.
Check: don't headline the latest value alone. Show the trend from Battery capacity history and point out sudden jumps.
Bonus: number formats
The report uses the system locale. 27,380 mWh on an English system can be 27.380 mWh or 27 380 mWh elsewhere. Strip everything that isn't a digit before parsing integer mWh values, and never parse them with parseFloat directly.
What I took from this
The battery report is the best free source of battery data on Windows, but it's firmware-reported data, not a measurement. Any tool that reads it should:
- Validate design capacity per row.
- Bound durations by the period length.
- Treat extreme standby estimates as noise until confirmed.
- Distinguish "not reported" from zero.
- Show trends, not just the latest value.
I've published the full numbers from all four laptops, including the glitches, as a small open dataset with a CSV: real laptop battery report data. To read your own report, the battery health checker runs entirely in the browser and doesn't upload the file.
Have you seen impossible values in your own battery report? I'd like to add more examples.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.