guide #055

termux-wake-lock + Doze Bypass

Problem
Doze mode suspends CPU after 30 min screen off. Telegram messages delayed 2-3 hours.

Solution
termux-wake-lock (PARTIAL_WAKE_LOCK) + deviceidle whitelist for Termux. CPU stays on, screen off.

Context

Android 6.0 introduced Doze mode: after 30 minutes of screen-off inactivity, the CPU is suspended to save battery. Periodic maintenance windows (increasing intervals: 15 min, 30 min, 1 hour, 2 hours) allow brief processing bursts. For a phone plugged into power running as a server, Doze is counterproductive — Telegram messages arrive 2-3 hours late because the CPU is suspended.

The solution is a PARTIAL_WAKE_LOCK via Termux's wake lock API, combined with Doze whitelist exemption.

Implementation

Two components: the wake lock and the Doze whitelist.

# In start-pocketclaw.sh (boot script):
termux-wake-lock 2>/dev/null

The Doze whitelist exemption is set once from ADB (persists across reboots):

# From ADB shell (one-time setup):
adb shell dumpsys deviceidle whitelist +com.termux
# Expected: Added: com.termux

# Verify whitelist:
adb shell dumpsys deviceidle whitelist
# Expected: system,com.termux,...

The GC logs prove the difference:

# Without wake lock — CPU suspended, gaps in GC:
# 14:00:00 [gc] freed 15 MB
# 16:30:00 [gc] freed 15 MB  (2.5 hour gap!)
# 18:45:00 [gc] freed 15 MB  (2.25 hour gap!)

# With wake lock — CPU active, regular GC:
# 14:00:00 [gc] freed 15 MB
# 14:00:30 [gc] freed 15 MB  (30s interval as configured)
# 14:01:00 [gc] freed 15 MB

Verification

# Check wake lock is held:
adb shell dumpsys power | grep "Wake Locks"
# Expected: shows Termux wake lock

# Check Doze whitelist:
adb shell dumpsys deviceidle whitelist | grep termux
# Expected: com.termux

# Check Doze state:
adb shell dumpsys deviceidle
# Expected: mState=ACTIVE (not IDLE)

# Verify Telegram responds promptly:
# Send a message to @pocketclawbot
# Expected: response within 5-10 seconds (not hours)

Gotchas

  • Wake lock requires the com.termux Dalvik VM to remain alive (48 MB RSS). Killing it releases the lock AND triggers a cgroup cascade that kills the gateway
  • On a plugged-in phone, battery impact is irrelevant. But if running on battery, wake lock will drain it in 4-6 hours
  • termux-wake-lock is a Termux-specific command that calls Android's PowerManager PARTIAL_WAKE_LOCK API
  • The Doze whitelist exemption persists across reboots. You only need to set it once
  • Some ROMs override Doze settings. If messages are still delayed, check manufacturer-specific battery optimization settings

Result

MetricBeforeAfter
Message delay2-3 hours5-10 seconds
CPU state (screen off)Suspended (Doze)Active
GC intervalErratic (hour gaps)Regular (30s)
Battery on powerN/AN/A (plugged in)
Continue reading
guide
Pocket AI complete guide
Running self-hosted AI on portable hardware
guide
Edge AI hardware buyer's guide 2026
Pi 5 vs Mini PC vs Mac Mini
report
Self-hosted AI landscape 2026
Quarterly state of the ecosystem
section
Pocket AI hardware hub
All portable hosts reviewed
section
Agent tracker
Live stats on every agent
newsletter
Thursday digest
Weekly summary in your inbox