73 lines
10 KiB
Markdown
Executable File
73 lines
10 KiB
Markdown
Executable File
---
|
||
title: 'CPM — metrics, causes and mitigations'
|
||
date: '2026-10-16'
|
||
tags:
|
||
- work
|
||
- cpm
|
||
- analysis
|
||
updated: '2026-10-20'
|
||
---
|
||
# CPM: metrics, causes and mitigations
|
||
|
||
Updated 20 October 2026. Internal metrics; keep these figures out of public PRs. Production figures retain their original date windows. `cpm-e2e-init` refers to the historical 16 October test worktree; current PRs and source paths are listed in [[cpm-status-2026-10-15]] and [[cpm-web-extension-code-guide-2026-10-09]].
|
||
|
||
## What the metrics mean
|
||
|
||
The monitor reports failure when no matching native dashboard refresh arrives within 4 seconds of navigation completion. A second qualifying timeout marks the episode stuck and triggers M4 extension reload. Neither timeout nor recovery proves delivery of `initResp` to the page: tests can receive it while dashboard delivery fails.
|
||
|
||
The production cut below uses the old separate daily pixels: installation-days per event/reason, not distinct users or paired episodes. Independently deduplicated failure/recovery totals cannot establish transition or recovery success rates. Keep `.count` separate from `.daily`.
|
||
|
||
The published #7376 branch changes this to one terminal `web_extension_cpm_episode`, daily+count. Daily counts installations with a completed episode; count counts completed episodes. A new baseline is required. Its current PR is closed without merge, so this is not a shipped-data claim. The four-state `stuck` and two-phase `bg_events` contract is documented in [[cpm-pr0-episode-telemetry-summary-2026-10-16]].
|
||
|
||
## Distribution
|
||
|
||
Latest received production cut: **12–14 October**, iOS 7.240+ / macOS 1.210+. Figures below always use **iOS / macOS** order.
|
||
|
||
- Initial failures: **3,273,025 / 119,950**; stuck: **511,660 / 40,842**.
|
||
- Recovery without reload: **1,135,477 / 30,738** (34.7% / 25.6% of initial-failure daily totals).
|
||
- Recovery after M4: **293,557 / 21,865** (57.4% / 53.5% of stuck daily totals); reload-failed reports: **140,921 / 17,796** (27.5% / 43.6%). These are ratios of event totals, not episode outcomes.
|
||
|
||
Mutually exclusive snapshot cohorts, in classification priority order. Each pair shows **share of initial failures → share of stuck**:
|
||
|
||
- Error 6: **6.1% → 21.5% / 1.0% → 1.9%**.
|
||
- No background view: **48.1% → 10.9% / 3.3% → 1.8%**.
|
||
- Tab detached: **0.03% → 0.05% / 6.2% → 8.9%**.
|
||
- Network process replaced: **16.8% → 39.7% / 13.6% → 26.6%**.
|
||
- Recent wake: **7.9% → 9.5% / 32.5% → 32.2%**.
|
||
- Recent context load: **15.7% → 6.0% / 20.0% → 6.4%**.
|
||
- Other: **5.3% → 12.5% / 23.4% → 22.2%**.
|
||
|
||
These classify observed state, not causes. Network replacement and error 6 are more prominent in stuck; missing-view and recent-load cases are less prominent.
|
||
|
||
Earlier **5 October post-release** cut: initial failures **6,624 / 1,377**, stuck **1,440 / 487**, first post-reload timeouts **670 / 232**. It established the same wake/load distinction; its different window and filters must not be combined with the newer totals. [[cpm-web-extension-public-attribution-2026-10-05|Original cut]] · [[cpm-web-extension-data-analysis-summary-2026-10-08|Earlier analysis]]
|
||
|
||
## Causes and suggested mitigations
|
||
|
||
Percentages below are shares of all initial-failure / stuck daily reports in the 12–14 October cut. Snapshot cohorts are proxies for causes; P5/P6 selections use separate denominators.
|
||
|
||
- **Network crash:** replacement cohort — **iOS init 16.8%, stuck 39.7%; macOS init 13.6%, stuck 26.6%**. reproduced across tabs/windows; a surviving background view can retain a dead worker after Network-process replacement. [#7459](https://github.com/duckduckgo/apple-browsers/pull/7459) restarts the background and now reports `web_extension_cpm_network_process_recovery_applied` (daily+count, no custom parameters). This counts application, not proven recovery or every crash. Production attribution remains incomplete: `network_restarted` compares against context load, not the latest view. Add `network_replaced_since_view`; the older analysis supports at most 20–45% of healthy-looking stuck reports, not the whole cohort.
|
||
- **P1, slow idle wake:** recent-wake cohort — **iOS init 7.9%, stuck 9.5%; macOS init 32.5%, stuck 32.2%**; excludes older wake tails. an imposed startup delay reproduces timeout followed by a late answer; natural production slowness remains unexplained. The published #7379 mitigation prepares background before navigation, with a shared, cancellable **5-second maximum wait**. It passed with an 8-second worker delay; longer delays remain possible.
|
||
- **P2, error 6:** error-6 cohort — **iOS init 6.1%, stuck 21.5%; macOS init 1.0%, stuck 1.9%**. controlled macOS suspension reproduces WebKit's roughly 30-second background-load timeout. The main iOS chains remain unproven. The published #7379 mitigation retries `loadBackgroundContent` once on the current context, with cooldown and recovery guards. Same-document dashboard **and page initResp** recovery passed twice. Full-context replacement was rejected after repeat page-response loss. Foreground-resume recovery remains untested.
|
||
- **P3, loaded context without view:** no-view cohort — **iOS init 48.1%, stuck 10.9%; macOS init 3.3%, stuck 1.8%**. startup dominates on iOS. Base-URL cleanup can delay startup, but the full P3 failure remains unreproduced, including the 20,000-resource cache test. [#7493](https://github.com/duckduckgo/apple-browsers/pull/7493) now implements a stable private extension origin, default ON with a remote kill switch, excluding installations with web-accessible resources. macOS tests verify origin continuity and removal of repeated migration; they still do not reproduce the complete production P3 failure. No new telemetry definitions are included.
|
||
- **P4, first mid-session load:** Fix A signature — **iOS init 3.9%, stuck 0.9%**. Broader recent-load cohort: **iOS init 15.7%, stuck 6.0%; macOS init 20.0%, stuck 6.4%**. early init loss is reproduced; #7379 waits for first background readiness and separately counts `web_extension_cpm_startup_response_missing` with daily+count even while late-document reload is disabled. Late-document reload remains default OFF. The narrower signature is 129k → 4.6k iOS reports and can include reloads.
|
||
- **P5, background fails to wake:** **5 October, after each platform's release tag: iOS init 1.40% (93 / 6,624) → stuck 2.08% (30 / 1,440); macOS init 6.83% (94 / 1,377) → stuck 4.52% (22 / 487)**. Recounted from the saved `cpm-public-attribution-2026-10-06/initialization_daily.tsv` and `events_daily.tsv`: last five `bg_events` names `proxy_on>dealloc>view>proxy_on>dealloc`, excluding error 6, Network replacement and scripts=false. This is the earlier 5 October cut, not 12–14 October. **14 October stuck: iOS 1.15% (1,953 / 169,115); macOS 3.57% (499 / 13,992)**; init for that newer cut has not been recounted. Closing a window with a shared pinned tab reproduces lost tab registration on macOS; fix window/tab lifecycle reporting. That signature appears in **13.6% of macOS P5** (68 / 499), or **0.49% of all macOS stuck**. Missing listener registration also reproduces P5 in controlled tests; its natural trigger remains unknown. The earlier 494-report selection used different filters.
|
||
- **P6, controller mismatch:** broader detached-tab cohort — **iOS init 0.03%, stuck 0.05%; macOS init 6.2%, stuck 8.9%**. P6-only init/stuck shares are unavailable. a main `webExtensions` flag cycle creates a new manager while existing web views retain the old controller. Recreate/rebind affected views when replacing the manager; context reload alone cannot repair this. The conditional mechanism is reproduced, but its occurrence in production is unconfirmed. Selected macOS tails: **627 + 235** reports.
|
||
- **Other:** **iOS init 5.3%, stuck 12.5%; macOS init 23.4%, stuck 22.2%**. Tests reproduce slow settings replies, lost messages, and missing dashboard confirmation even when the page receives its answer. Some iOS reports also resemble slow wake-up (P1). Their individual shares are unknown. Mitigations depend on which step fails: wait for background readiness, reduce settings delays, or fix message/confirmation delivery.
|
||
|
||
## PR status and local validation
|
||
|
||
Verified from GitHub on 20 October 2026; exact heads and CI failure annotations are in [[cpm-status-2026-10-15#2. PR и quality gates]].
|
||
|
||
- #7376 `5d1cb4abd2`: **closed without merge**, approved, CI green. macOS #7484 `3fb13b81fe`: open, CI green, but release-base conflict and earlier telemetry contract.
|
||
- #7379 `674bb809f2`: open on the telemetry branch; **BSK CI failed** on a crashed ConfigurationFetcher XCTest. Earlier green results below belong to their tested revisions.
|
||
- #7459 `f41c7b7047`: current Network recovery plus applied pixel; open, CI green.
|
||
- #7493 `dd96018da9`: stable-origin P3 path; open, CI green, full P3 failure still unreproduced.
|
||
- [#7473](https://github.com/duckduckgo/apple-browsers/pull/7473) `574e9288ae`: shared-pinned window-close P5 fix **merged 20 October 2026 into `release/macos/1.213.0`**, commit `9bcce0264e`; CI green. Unit tests now assert WebKit `openTabs`; the real-window fixture remains local, with ON 9 → OFF 5 expected failures + 1 control → ON 27 PASS. It fixes one mechanism; release publication, rollout and production effect remain unverified. Details: [[cpm-status-2026-10-15#P5 — merged 20 октября 2026]].
|
||
- #7378 harness and #7384 baseline are closed without merge. #7385/native progress and extension #3727 remain open; #7385 still depends on the closed baseline branch. Old #7381 is still open but is not the current Network recovery implementation.
|
||
|
||
Readiness timing does not establish message delivery. The episode report still lacks page ACK/last confirmed stage, a final result for initially pending loads, and network replacement relative to its current view. Late errors before stuck can now appear in the history continuation; non-stuck reports keep only their initial history. See [[cpm-status-2026-10-15#6. Телеметрия]].
|
||
|
||
**Historical local `cpm-e2e-init`, 16 October:** P1/P2 candidates were uncommitted at that point; the current implementation is in #7379. **22 unique app methods passed across separate runs**; two deliberate disabled-fix controls failed. Package validation: **806 tests, 14 skipped, zero failures**. Tests use real app/WebKit paths with an instrumented bundle and imposed faults; they do not identify every production cause. P3 remains unreproduced; app P5 establishes one lost navigation. No shipped-effect claim.
|
||
|
||
Detailed evidence and final validation: [[cpm-status-2026-10-15]] · [[cpm-web-extension-code-guide-2026-10-09]].
|