Power budgets: making a battery ESP32 project last
Duty cycles, deep sleep, regulators that leak and the multimeter habit that saves you from surprises. A practical guide to battery life on ESP32 boards.
Every battery-powered ESP32 project eventually asks the same question: why did it die after three days? The answer is almost always a power budget nobody wrote down. Here's how I write one.
Think in averages, not peaks
A device's battery life depends on its average current. For a device that wakes, does work and sleeps, the average is a weighted sum:
I_avg = (I_active × t_active + I_sleep × t_sleep) / (t_active + t_sleep)
Say a sensor wakes every 5 minutes, spends 2 seconds connecting to Wi-Fi and sending a reading at ~120 mA average, then sleeps at 20 µA:
active: 120 mA × 2 s = 240 mA·s
sleep: 0.02 mA × 298 s ≈ 6 mA·s
average: 246 / 300 ≈ 0.82 mA
A 2,000 mAh battery at 0.82 mA is roughly 2,400 hours — about 100 days, before derating for battery chemistry, temperature and self-discharge. Notice that the 2 seconds awake cost forty times more than the 298 seconds asleep. That's where your optimization effort belongs.
Shorten the awake time
- Avoid full Wi-Fi association when you can. Static IP instead of DHCP, cached channel and BSSID, or ESP-NOW to a gateway can cut connection time dramatically.
- Batch your work. Take ten readings, send once.
- Do the minimum before sleeping again. Logging, pretty printing and debug output all cost time.
Make sleep actually sleep
The ESP32 chip itself can reach very low deep-sleep currents. Your board often can't, and the culprits are predictable:
- Linear regulators with high quiescent current. Some popular LDOs burn more current idling than the ESP32 does asleep. Choose a low-Iq regulator.
- USB-serial chips and power LEDs on dev boards draw current constantly. A dev board is not a battery product.
- Pull-up resistors on buttons or buses leak current through anything holding the line low.
- Sensors left powered. Switch peripheral power with a MOSFET or a load switch, and turn it off before sleeping.
Measure, don't estimate
Datasheet numbers are best case. Your board is the real case. I measure three things on every battery design:
- Sleep current with a meter that can resolve microamps.
- Active current profile over a full wake cycle, with a current probe or a power profiler.
- Wake duration from logs or a GPIO toggled at wake and sleep, watched on a scope.
Then I put the real numbers back into the budget. The first time you do this, it's humbling.
Brownouts: the other battery problem
Batteries sag under load, and Wi-Fi transmit bursts are big loads. If the supply dips during a transmit, the ESP32's brownout detector resets the chip, which retries Wi-Fi, which draws more current... a nasty loop. Defenses:
- Enough bulk capacitance near the module.
- A regulator that can handle the peak current with headroom.
- Low-resistance battery connections and wiring.
Write it in the design doc
My power budget lives in the project's README, right next to the pinout table: modes, currents, durations, expected battery life and the measured numbers. When something changes — a new sensor, a different wake interval — the budget changes with it.
Battery life isn't a feature you add at the end. It's a number you design toward from the start.
Some links in these notes are affiliate links. If you buy through one, I may earn a commission at no extra cost to you. I only link to tools I use or would recommend.