Check your Mac's real battery health in under a minute
Two commands, 0.12 seconds of actual runtime, and you get both the number Settings shows you and the raw one underneath it. No apps, no installs, no permissions.
Two commands give you everything macOS knows about your battery’s condition, including a figure Settings does not show. The whole thing runs in 0.12 seconds, needs no privileges and installs nothing.
Step 1: the raw capacities
ioreg -rn AppleSmartBattery | grep -oE '"(DesignCapacity|NominalChargeCapacity|AppleRawMaxCapacity|CycleCount)" = [0-9]+'
On the test machine:
"NominalChargeCapacity" = 5869
"DesignCapacity" = 6249
"CycleCount" = 190
"AppleRawMaxCapacity" = 5717
Capacities are in milliamp-hours. DesignCapacity is what the cell was rated at when new, and it is the denominator for everything that follows.
Step 2: what macOS displays
system_profiler SPPowerDataType | grep -iE "cycle count|condition|maximum capacity"
Cycle Count: 190
Condition: Normal
Maximum Capacity: 94%
Step 3: the arithmetic
Two divisions, both against DesignCapacity:
NominalChargeCapacity 5869 / 6249 = 93.92% -> rounds to the 94% Settings shows
AppleRawMaxCapacity 5717 / 6249 = 91.49% -> the unsmoothed reading
The first reproduces the displayed figure exactly, which confirms which field macOS uses. The second is 2.43 percentage points lower.
Both are real. NominalChargeCapacity is the battery controller’s filtered estimate, updated slowly and resistant to outliers. AppleRawMaxCapacity is close to the raw gauge inference, and it moves with temperature and recent charge history. Settings shows the stable one, which is the sensible choice for a number people glance at.
Doing it in one command
If you would rather not divide by hand:
ioreg -rn AppleSmartBattery | awk '
/"DesignCapacity"/ {gsub(/[^0-9]/,""); d=$0}
/"NominalChargeCapacity"/ {gsub(/[^0-9]/,""); n=$0}
/"AppleRawMaxCapacity"/ {gsub(/[^0-9]/,""); r=$0}
/"CycleCount"/ {gsub(/[^0-9]/,""); c=$0}
END {
printf "Design : %d mAh\n", d
printf "Nominal : %d mAh (%.2f%%) <- what Settings rounds and shows\n", n, n/d*100
printf "Raw gauge : %d mAh (%.2f%%) <- unsmoothed\n", r, r/d*100
printf "Cycles : %d\n", c
}'
Design : 6249 mAh
Nominal : 5869 mAh (93.92%) <- what Settings rounds and shows
Raw gauge : 5717 mAh (91.49%) <- unsmoothed
Cycles : 190
The field to ignore
Most guides that cover this topic tell you to read MaxCapacity. On this machine:
ioreg -rn AppleSmartBattery | grep -oE '"MaxCapacity" = [0-9]+'
"MaxCapacity" = 100
At 190 cycles with genuine wear of 6 to 8 percent, it reports 100. On Apple Silicon that field is normalised and pinned; it is not a health figure. On Intel Macs it held an absolute capacity in milliamp-hours and dividing it by DesignCapacity gave a meaningful ratio, which is why the advice persists. Anything recommending it was written for different hardware and never re-tested.
Tracking it over time
A single reading tells you almost nothing, particularly the raw one, which moves with temperature. A monthly log tells you the slope, which is the useful part.
# Append one line per run to a log
ioreg -rn AppleSmartBattery | awk -v d="$(date +%F)" '
/"DesignCapacity"/ {gsub(/[^0-9]/,""); dc=$0}
/"NominalChargeCapacity"/ {gsub(/[^0-9]/,""); n=$0}
/"AppleRawMaxCapacity"/ {gsub(/[^0-9]/,""); r=$0}
/"CycleCount"/ {gsub(/[^0-9]/,""); c=$0}
END {printf "%s,%d,%.2f,%.2f\n", d, c, n/dc*100, r/dc*100}
' >> ~/battery-log.csv
Columns are date, cycles, nominal percent, raw percent. Run it once a month and the trend becomes visible long before the displayed whole-number percentage ticks down.
Interpreting what you get
Cycle count matters as much as the percentage. Current Mac notebook batteries are rated to retain 80 percent of original capacity at 1000 cycles. At 190 cycles this machine is 19 percent through its rated life and has lost about 6 percent of capacity by the displayed measure, which is ahead of the curve rather than behind it.
Apple’s service conversation is anchored on the displayed percentage falling below 80. That is the number to use when deciding about a replacement, because it is the number a service provider will also read. The raw figure is for watching the slope, not for arguing with anybody.
If Condition reports anything other than Normal, that outranks both percentages and is worth acting on.
What else the controller will tell you
The four fields above are the ones that answer the health question. The battery publishes considerably more, and three additional values are worth knowing about.
ioreg -rn AppleSmartBattery | grep -oE '"(Temperature|Voltage|InstantAmperage|AppleRawCurrentCapacity)" = -?[0-9]+'
Temperature is in hundredths of a degree Celsius, so 2980 means 29.8 degrees. This matters
because capacity readings move with temperature, and a raw figure taken on a cold machine will
read worse than the same battery an hour later. If you are logging the raw value over time,
logging temperature alongside it turns an unexplained wobble into an explained one.
Voltage is in millivolts across the whole pack. InstantAmperage is in milliamps and goes
negative while discharging. Multiplied together they give instantaneous power draw:
ioreg -rn AppleSmartBattery | awk '
/"Voltage"/ {gsub(/[^0-9]/,""); v=$0}
/"InstantAmperage"/ {gsub(/[^0-9-]/,""); a=$0}
END {printf "%.2f W\n", (v/1000) * (a/1000) * -1}'
That is a genuine power measurement, taken from the battery’s own gauge, with no privileges
required. It is the whole system rather than the CPU alone, so it will not match a
powermetrics CPU figure, and for the question of how fast the battery is actually draining it
is the more directly relevant number.
Cycle count, and what a cycle is
A cycle is not a charge. It is a full discharge worth of energy, accumulated however it happens. Draining from 100 to 50 percent twice is one cycle. Topping up from 90 to 100 percent ten times is also one cycle.
This is why cycle count rises slowly for someone who works plugged in and quickly for someone who runs the machine flat daily, even if both plug in the same number of times. Current Mac notebook batteries are rated to retain 80 percent of original capacity at 1000 cycles, so the figure gives you a rough position on the wear curve.
At 190 cycles this machine is roughly 19 percent through its rated life and has lost about 6 percent of capacity by the displayed measure. Wear is not linear, so extrapolating a straight line from those two numbers to predict the replacement date will be wrong, but the direction is informative.
Optimised charging and why the number sometimes stalls
If your displayed percentage has not moved in months, that is usually working as intended rather than a stuck reading.
macOS runs battery health management, which limits maximum charge when it detects a pattern of long periods on AC power. The battery sits at around 80 percent instead of 100, which substantially slows chemical ageing. Under that regime capacity loss genuinely does nearly stop, and the displayed percentage genuinely does stay put.
pmset -g | grep -iE "lowpowermode|powernap"
system_profiler SPPowerDataType | grep -iE "condition|charging"
The trade is that the machine does not hold a full charge when you unplug it and leave. That is a real cost on a travel day and close to free otherwise, which is why it is on by default.
When the two numbers disagree more than usual
A gap of two to three percentage points between the displayed figure and the raw one is normal. A much larger gap is worth a second reading rather than a conclusion.
The most common cause is temperature: a raw reading taken on a machine that has been under load or in a warm room will diverge further from the filtered value. The second most common is a recent deep discharge, which leaves the gauge’s model temporarily out of step until it recalibrates over the next few charge cycles.
If a large gap persists across several readings taken days apart at similar temperatures, that is
the point at which it is telling you something, and the Condition field is worth more attention
than either percentage.
The whole thing, as one function
batteryhealth() {
ioreg -rn AppleSmartBattery | awk '
/"DesignCapacity"/ {gsub(/[^0-9]/,""); d=$0}
/"NominalChargeCapacity"/ {gsub(/[^0-9]/,""); n=$0}
/"AppleRawMaxCapacity"/ {gsub(/[^0-9]/,""); r=$0}
/"CycleCount"/ {gsub(/[^0-9]/,""); c=$0}
END {
printf "displayed %.0f%% (nominal %d of %d mAh)\n", n/d*100, n, d
printf "raw gauge %.2f%% (%d mAh)\n", r/d*100, r
printf "cycles %d\n", c
}'
system_profiler SPPowerDataType | grep -i condition
}
Add it to ~/.zshrc and the whole check is one word.
Takeaways
- The whole procedure runs in 0.12 seconds and needs no sudo, no install and no privacy grant.
- NominalChargeCapacity divided by DesignCapacity reproduces the percentage macOS shows, rounded.
- AppleRawMaxCapacity gives the unsmoothed reading, which moves earlier than the displayed figure.
- MaxCapacity reads a fixed 100 on Apple Silicon and should be ignored, despite most guides recommending it.
Questions
- Do I need to install anything?
- No. ioreg and system_profiler both ship with macOS, and neither needs sudo or Full Disk Access for these particular queries.
- How often should I check?
- Monthly is enough to build a trend. Daily readings mostly measure temperature and recent charging rather than genuine wear.
- What counts as a bad number?
- Apple's service guidance is built around the displayed percentage dropping below 80. Cycle count matters too: batteries in current Mac notebooks are rated to hold 80 percent at 1000 cycles.
Sources
What we read. Distinct from what we measured, which is in the article itself.