Skip to content

Chronic background ANRs (FCMBroadcastReceiver, NotificationDismissReceiver, BootUpReceiver, SyncJobService) unchanged after 5.9.5 prewarm (PR #2664) — version-code data #2709

Description

@marcoscashea

Description

Following up on the background-ANR fixes in 5.9.5 (SDK-4794 / PR #2664, prewarm at cold-start entry points) and 5.9.6 (SDK-4822, app-state-aware watchdog). We're still seeing chronic background ANRs on FCMBroadcastReceiver, NotificationDismissReceiver, BootUpReceiver, and SyncJobService on the current SDK, and have version-code-sliced Play Vitals data showing the 5.9.5 prewarm did not measurably reduce them for us.

Setup

  • onesignal_flutter: was 5.6.3, now 5.6.7 (native Android 5.9.5 → 5.9.8) as of this report
  • App: Flutter, Android minSdk 24 / targetSdk 36
  • Device mix skews heavily to budget/entry-level hardware: Tecno, Infinix, Honor, entry-level Redmi and Samsung Galaxy A-series

What we measured

We pulled Google Play Vitals (Android Developer Reporting API), sliced by app version code, comparing builds before and after our 5.6.3 upgrade (which shipped 2026-06-29, pulling in native 5.9.5 and the SDK-4794 prewarm):

Component (issue) users, all builds (7d) users, builds with 5.6.3+ share unchanged
FCMBroadcastReceiver 16,439 16,008 97.4%
NotificationDismissReceiver 5,963 5,907 99.1%
FCMBroadcastReceiver (2nd issue) 3,024 3,005 99.4%
NotificationDismissReceiver (2nd issue) 2,561 2,536 99.0%
BootUpReceiver 805 794 98.6%
SyncJobService 225 216 96.0%

Normalized against install-base drift (OneSignal's share of all Android ANR reports in the same 7-day window, to control for how many devices are on each build): 34.8% pre-5.6.3 → 62.3% post-5.6.3. The upgrade is fully rolled out on our current builds and the cluster is, if anything, a larger share of our total ANR volume than before.

All four components use goAsync() then suspendifyOnIO { ... } (confirmed by reading the 5.9.8 sources). Every ANR dump in this cluster (100+ per capture) shows the main thread idle in nativePollOnce/epoll_pwait with no Runnable thread other than the ART dump-generation thread — which we understand is expected, since goAsync() does not extend the broadcast/service ANR budget; the clock runs from process start through onReceive()/onStartJob() until PendingResult.finish()/job completion, regardless of whether the work moved to a background dispatcher.

Relation to PR #2664

That PR's description explicitly frames prewarming at entry points as the accepted-tradeoff option, over the rejected "durable" option (queue the first dispatch so cold dispatcher construction can never land on a caller thread), specifically because "we have not proven [the race] still fires" in production telemetry, and calls out that "a pathologically slow device could still lose the race."

We believe our fleet is exactly that device population, and the data above is the telemetry that would justify revisiting the durable option — or at minimum, understanding why the prewarm isn't winning the race for us. Happy to share the raw Vitals export (with PII already stripped by the Play Reporting API) if useful for triage.

Ask

  • Does the prewarm in SDK-4794 have a known gap for devices this slow (e.g., is there a lower bound on how much lead time it needs before the first suspendifyOnIO dispatch, and could that lead time not be met on a cold goAsync() handoff on this hardware class)?
  • Is there interest in revisiting the "durable" option from PR fix: [SDK-4794] prewarm dispatchers at cold-start entry points #2664 (queueing the first dispatch) given production telemetry that the race is still lost at meaningful volume?
  • Is there a way to reduce what runs inside initWithContext + the bundle/restore/sync work specifically for cold-background entry points, independent of the dispatcher-construction race?

Happy to provide more detail — version codes, API level breakdown, or raw thread dumps — whatever's useful.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions