Please answer the following questions for yourself before submitting an issue
AdGuard version
4.12.81
Environment
- Device: Samsung Galaxy S23+
- OS version: Android 16
HTTPS filtering
Root access
Integration with AdGuard VPN
Routing mode
Local VPN
Ad Blocking
No response
Privacy
No response
Social
No response
Annoyances
No response
Security
No response
Language-specific
No response
Other
No response
Which DNS server do you use?
Custom DNS
DNS protocol
DNS-over-QUIC
Custom DNS
nextdns.com
What Stealth Mode options do you have enabled?
No response
Issue Details
Steps to reproduce:
- Run AdGuard in integrated filtering (local VPN) mode.
- Idle the device screen-off for 1–2 h.
adb shell dumpsys alarm → observe *walarm*:com.adguard.android.watchdog.CHECK_ALIVE firing repeatedly at its configured interval with flags=0x9.
Expected Behavior
The watchdog should not hold the device out of deep sleep via an exact, unthrottled, Doze-bypassing alarm on a short interval and ensure the watchdog setting actually stops/adjusts the alarm when changed.
Actual Behavior
With AdGuard running, the device suffers heavy idle (screen-off) battery drain — about 5%/hour in a controlled idle window, well above a normal idle baseline. The watchdog wakes the device repeatedly at its configured interval, around the clock, preventing it from settling into deep sleep.
Screenshots
No response
Additional Information
The wakeups come from AdGuard's protection watchdog. From dumpsys alarm:
tag=*walarm*:com.adguard.android.watchdog.CHECK_ALIVE
type=RTC_WAKEUP window=0 exactAllowReason=permission repeatInterval=0 count=0 flags=0x9
operation=PendingIntent{... com.adguard.android startService}
repeatInterval=0 with a fresh origWhen each cycle → a one-shot alarm that re-arms itself each interval.
- The alarm is exact (
exactAllowReason=permission) and carries flags=0x9 = FLAG_STANDALONE | FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED, so it bypasses Doze throttling and fires unthrottled while the device is idle.
- AdGuard receives this unrestricted treatment because, as the active VPN, its UID is auto-added to the system power allowlist (
mDeviceIdleWhitelist).
Measured evidence:
- In a focused CPU-wakeup capture, ~89% of all device wakeups (530 of 597) were attributed to AdGuard's foreground service; kernel wake source is the PMIC RTC alarm (
pm8xxx_rtc_alarm).
- In an Airplane-Mode + Wi-Fi/BT-off run, every other subsystem (Wi-Fi, sensors) was silent for ~1h54m while this alarm kept firing on its interval — confirming a local, network-independent alarm.
- The
CHECK_ALIVE tag appears thousands of times across the battery-history dump, consistent with its short configured interval (thousands of fires per day).
Additional finding: disabling the watchdog in settings did not stop it.
Please answer the following questions for yourself before submitting an issue
AdGuard version
4.12.81
Environment
HTTPS filtering
Root access
Integration with AdGuard VPN
Routing mode
Local VPN
Ad Blocking
No response
Privacy
No response
Social
No response
Annoyances
No response
Security
No response
Language-specific
No response
Other
No response
Which DNS server do you use?
Custom DNS
DNS protocol
DNS-over-QUIC
Custom DNS
nextdns.com
What Stealth Mode options do you have enabled?
No response
Issue Details
Steps to reproduce:
adb shell dumpsys alarm→ observe*walarm*:com.adguard.android.watchdog.CHECK_ALIVEfiring repeatedly at its configured interval withflags=0x9.Expected Behavior
The watchdog should not hold the device out of deep sleep via an exact, unthrottled, Doze-bypassing alarm on a short interval and ensure the watchdog setting actually stops/adjusts the alarm when changed.
Actual Behavior
With AdGuard running, the device suffers heavy idle (screen-off) battery drain — about 5%/hour in a controlled idle window, well above a normal idle baseline. The watchdog wakes the device repeatedly at its configured interval, around the clock, preventing it from settling into deep sleep.
Screenshots
No response
Additional Information
The wakeups come from AdGuard's protection watchdog. From
dumpsys alarm:repeatInterval=0with a freshorigWheneach cycle → a one-shot alarm that re-arms itself each interval.exactAllowReason=permission) and carriesflags=0x9=FLAG_STANDALONE | FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED, so it bypasses Doze throttling and fires unthrottled while the device is idle.mDeviceIdleWhitelist).Measured evidence:
pm8xxx_rtc_alarm).CHECK_ALIVEtag appears thousands of times across the battery-history dump, consistent with its short configured interval (thousands of fires per day).Additional finding: disabling the watchdog in settings did not stop it.