ZeroTrace AirLeak
Safe Mode
How and when the firmware self-protects under heap pressure
Safe mode is a self-protective state the firmware enters when free internal heap drops dangerously low. It's designed to keep the unit responsive instead of crashing under extreme load.
What triggers safe mode
The heap monitor task samples free internal heap every 250 ms. Safe mode triggers when:
heap_free_pct < 7% AND sustained for ≥ 2 consecutive samples
Two-sample-sustained avoids tripping on momentary allocations. Real heap exhaustion takes seconds to develop; transient spikes are normal during heavy decode bursts.
What safe mode does
Once triggered, the firmware:
- Suspends the WiFi capture task. WiFi promiscuous mode allocates the largest queues — pausing it frees ~30 KB internal heap immediately.
- Drops the BLE scan duty cycle. Active scan window is halved (e.g. 75 ms → 38 ms). The radio still scans but emits half as many SCAN_REQ bursts.
- Doubles the throttle. A 1000 ms throttle becomes 2000 ms while in safe mode. Fewer events stream → less queue pressure.
- Sets
safe_mode = truein the heartbeat. The desktop status bar shows the safe-mode indicator (red). - Emits a
LOG: safe-mode armedline. Visible in the device log tab.
The unit stays in safe mode until heap recovers above 12 %. At that point:
- WiFi capture resumes
- BLE scan duty cycle restores to configured value
- Throttle restores
safe_mode = falseLOG: safe-mode clearedemitted
When safe mode happens in real life
Safe mode is rare in normal use. The default 1 s throttle and the 768-slot aggregator are sized to keep heap above 10 % in typical environments (50–60 devices).
You'll see safe mode arm in:
| Scenario | Reason |
|---|---|
| Very dense environment (100+ devices) | Aggregator + per-device JSON encoding fills heap |
| Throttle accidentally set to 0 in a busy area | Stream queues fill |
| Long capture without ever switching to Setup | Slow heap fragmentation |
| USB-CDC desktop not draining (frozen / slow) | Output queue fills |
| BLE scan window set to 100 ms in 100 ms interval (100 % duty cycle) under heavy load | Scan callbacks queue faster than parser drains |
How to recover
Most of the time, safe mode auto-recovers within seconds — the throttle increase and WiFi pause clear enough heap quickly.
If safe mode persists for more than a minute:
-
Switch to Setup mode briefly. This stops radio capture entirely, lets all queues drain. After 5 seconds, switch back to Monitor.
-
Increase the throttle. If safe mode keeps recurring, the environment is denser than the throttle is sized for. Raise to 2000 ms or 3000 ms.
-
Reduce channel coverage. Cut the channel-hop list to non-overlapping channels (
airleak-channels 1,6,11). Fewer channels means less data per second. -
Restart the unit.
airleak-restartclears all heap state. Settings are preserved.
If safe mode triggers immediately on every boot, the firmware itself may be wedged. Try factory reset or reflash via the Web Flasher.
What you lose during safe mode
While safe mode is active:
- WiFi events stop arriving. No new beacons, probe-requests, deauths in the desktop.
- BLE update rate halves. Devices still update but at half cadence.
- Stream feels slower. Throttle is doubled; fewer events on the wire.
The aggregator and alert engine continue running normally on whatever the BLE side captures. Existing devices keep updating, alerts keep firing — just at reduced WiFi visibility and lower BLE rate.
No state is lost. Safe mode is a throttle, not a reset. When it clears, capture resumes at full duty cycle from where it left off.
Reading safe-mode state
In the heartbeat:
safe_mode=true
heap_free=18432 (5%)
heap_min_ever=14112 (4%)
Or in the device log:
LOG: safe-mode armed (heap=18432, 5%)
LOG: WiFi capture suspended
LOG: BLE scan duty halved (38ms / 100ms)
LOG: throttle elevated (2000ms)
When safe mode clears:
LOG: heap recovered (43820, 13%)
LOG: safe-mode cleared
LOG: WiFi capture resumed
LOG: BLE scan duty restored (75ms / 100ms)
LOG: throttle restored (1000ms)
Safe mode and the desktop
The desktop visibly indicates safe mode in:
- Status bar Heap chip → red, with
(safe-mode)suffix - Heap chart on Overview → red region annotation showing safe-mode duration
- Device log →
LOG: safe-mode armedlines highlighted
If you see safe mode triggering frequently, the throttle and channel settings need tuning for your environment.
Why safe mode instead of crash
Without safe mode, a heap-exhausted ESP32-S3 would:
- Fail to allocate new RTOS queues → trigger
assert(...)failure - Trigger ESP-IDF guru-meditation panic
- Watchdog reset the chip
- Lose all in-RAM state (aggregator, alert ring, fingerprint cache)
- Trigger desktop reconnect (and lose the live session continuity)
Safe mode keeps the unit alive, draining whatever pressure caused the issue, and resuming when memory is healthy. It's the difference between a brief slowdown and a full reset.
Persistent safe-mode events mean your throttle is too low for the environment. Tune up:
airleak-throttle 2000
airleak-channels 1,6,11
Or, if you need full-channel coverage at low throttle, reduce the BLE scan window (airleak-scan-window 50) to give the parser more headroom.