Lane: reference (validated results). Vloom-GP (ub456dmer2m8), Android only, every install the app has. Method: creative_value_model.md §6, fleet_country_analysis.md §1–2, §6. Numbers: ../_runs/2026-07-29_payer_rate_analysis/, ../_runs/2026-07-30_payer_rate_zh/.
Metric names are Adjust's own: ARPU all_revenue_total_per_user_dN, ARPPU revenue_total_per_paying_user_dN, payer rate paying_user_conversion_rate_dN, repurchase revenue_events_total_per_paying_user_dN. Sections 1–8 are figures; findings are in §9. Measurement caveats in §11.
Today is 2026-07-30, so each cohort has only aged as far as the calendar allows. Cohort age dN of install day D is calendar day D+N, which caps what any row can show.
| Install day | Installs | Age today | d0 payer rate | d0 ARPU | d0 ARPPU | Payer rate at last complete age |
|---|---|---|---|---|---|---|
| 07-24 (Fri) | 171 | 6 | 2.92% | $0.4160 | $14.23 | 5.26% (d5) |
| 07-25 (Sat) | 236 | 5 | 5.08% | $0.3864 | $7.60 | 7.63% (d4) |
| 07-26 (Sun) | 259 | 4 | 5.41% | $0.4790 | $8.86 | 8.11% (d3) |
| 07-27 (Mon) | 1,307 | 3 | 5.89% | $0.6736 | $11.43 | 7.42% (d2) |
| 07-28 (Tue) | 707 | 2 | 2.26% | $0.3808 | $16.83 | 2.40% (d1) |
| 07-29 (Wed) | 962 | 1 | 3.43% | $0.2781 | $8.11 | 3.43% (d0) |
| 07-30 (running) | 510 | 0 | 3.33% | $0.2935 | $8.81 | — |
No cohort has a settled number. Only 07-24 has a complete d5; 07-25 reaches d4. The 07-28 cohort has one complete day beyond install (d1) and 07-29 has none. 07-30's figures move while the day runs.
Days before 07-24 carry 1–32 installs each and are excluded from every test below.
95% confidence intervals on the d0 payer rate:
| Install day | d0 payer rate | 95% CI |
|---|---|---|
| 07-24 | 2.92% | [1.26%, 6.66%] |
| 07-25 | 5.08% | [2.93%, 8.68%] |
| 07-26 | 5.41% | [3.25%, 8.87%] |
| 07-27 | 5.89% | [4.74%, 7.30%] |
| 07-28 | 2.26% | [1.40%, 3.64%] |
| 07-29 | 3.43% | [2.44%, 4.78%] |
The five complete days genuinely differ from each other — this is not day-to-day noise (χ² = 15.28, 4 dof, p = 0.0042). 07-27 against 07-28 is a real drop, not a fluctuation: 2.60×, Fisher p = 1.33 × 10⁻⁴.
ARPU = payer rate × ARPPU, exactly.
| d0 payer rate | × d0 ARPPU | = d0 ARPU | |
|---|---|---|---|
| 07-27 | 5.89% | $11.43 | $0.6736 |
| 07-28 | 2.26% | $16.83 | $0.3808 |
| change | ×0.38 | ×1.47 | ×0.57 |
ARPPU range across the window: $7.60 – $16.83. Pre-break range (07-24 to 07-27): $7.60 – $14.23. Repurchase across the break: 1.65 → 1.69 → 1.67.
ARPPU also holds as each cohort ages, so this is not a d0 artifact (this metric's denominator is paying users, which grows rather than collapses — §11):
| Install day | d0 | d1 | d2 | d3 |
|---|---|---|---|---|
| 07-26 | $8.86 | $8.94 | $9.13 | $9.32 |
| 07-27 | $11.43 | $12.36 | $12.32 | $12.41* |
| 07-28 | $16.83 | $16.18 | $16.18* | — |
Cells past a cohort's honest age are blank; * marks the age whose calendar day is still running. Both tables use a fixed d0 denominator (§11 explains why Adjust's own _dN fields cannot be read directly here).
Payer rate. The × after each day is that day's step (dN ÷ d(N−1)); the last column is cumulative from d0 to the last complete day.
| Install day | d0 | d1 | × | d2 | × | d3 | × | d4 | × | d5 | × | d0 → last complete |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-24 | 2.92% | 2.92% | 1.00× | 4.09% | 1.40× | 4.68% | 1.14× | 4.68% | 1.00× | 5.26% | 1.12× | 1.80× (d5) |
| 07-25 | 5.08% | 5.51% | 1.08× | 7.20% | 1.31× | 7.63% | 1.06× | 7.63% | 1.00× | 7.63%* | 1.00× | 1.50× (d4) |
| 07-26 | 5.41% | 7.34% | 1.36× | 7.72% | 1.05× | 8.11% | 1.05× | 8.11%* | 1.00× | — | — | 1.50× (d3) |
| 07-27 | 5.89% | 7.04% | 1.19× | 7.42% | 1.05× | 7.57%* | 1.02× | — | — | — | — | 1.26× (d2) |
| 07-28 | 2.26% | 2.40% | 1.06× | 2.40%* | 1.00× | — | — | — | — | — | — | 1.06× (d1) |
| 07-29 | 3.43% | 3.53%* | 1.03× | — | — | — | — | — | — | — | — | — (d0 only) |
ARPU, recomputed on the same fixed denominator:
| Install day | d0 | d1 | × | d2 | × | d3 | × | d4 | × | d5 | × | d0 → last complete |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-24 | $0.4160 | $0.4160 | 1.00× | $0.4906 | 1.18× | $0.5729 | 1.17× | $0.5729 | 1.00× | $0.6066 | 1.06× | 1.46× (d5) |
| 07-25 | $0.3864 | $0.4254 | 1.10× | $0.5689 | 1.34× | $0.6574 | 1.16× | $0.6574 | 1.00× | $0.6574* | 1.00× | 1.70× (d4) |
| 07-26 | $0.4790 | $0.6212 | 1.30× | $0.6342 | 1.02× | $0.6480 | 1.02× | $0.6480* | 1.00× | — | — | 1.35× (d3) |
| 07-27 | $0.6736 | $0.7658 | 1.14× | $0.7827 | 1.02× | $0.7881* | 1.01× | — | — | — | — | 1.16× (d2) |
| 07-28 | $0.3808 | $0.3889 | 1.02× | $0.3889* | 1.00× | — | — | — | — | — | — | 1.02× (d1) |
| 07-29 | $0.2781 | $0.2818* | 1.01× | — | — | — | — | — | — | — | — | — (d0 only) |
Most of the accrual lands in the d1–d3 steps and is spent by d4 on both metrics.
The last column of each table is measured to a different depth per row — d5 for 07-24 down to d1 for 07-28 — so it does not read down the column as a trend. Compare the × step columns, which are at equal depth.
07-25, 07-26 and 07-27 show no difference from each other at d1 (χ² = 0.828, 2 dof, p = 0.6609), so it is fair to treat them as one baseline. Compared against that baseline three ways:
Every cohort is truncated to a common age before comparing. Payer rate accrues with age, so reading each cohort at whatever depth it happens to have reached would credit the older group with extra days of accrual and inflate the gap by construction.
| Age compared at | Post-break | Pre-break | Ratio | Fisher p |
|---|---|---|---|---|
| d0 — all six cohorts complete | 49 / 1,669 = 2.94% | 103 / 1,802 = 5.72% | 1.95× | 6.10 × 10⁻⁵ |
| d1 — 07-28 against the three pre-break days, all cut to d1 | 17 / 707 = 2.40% | 124 / 1,802 = 6.88% | 2.86× | 4.41 × 10⁻⁶ |
Both say the difference is statistically significant. 07-29 is absent from the d1 row because its d1 is still running; no cohort on either side has a complete d2 or deeper on both sides of the break, so d1 is as deep as a like-for-like comparison can currently go.
Payer arrival profile. Only the two oldest cohorts can carry one. Pooling 07-24 and 07-25 (407 installs, 27 payers), the share of a cohort's eventual payers present by each age is d0 63.0%, d1 66.7%, d2 88.9%, d3 96.3%, d5 100%. That base is 27 people, so the profile is an order of magnitude rather than a measurement.
Per creative, d0 payer rate:
| Creative | 07-27 | 07-28 |
|---|---|---|
vid_utility_6s_9x16_v1 | 11.39% | 2.20% |
vid_sasian_bodysuit_10s_9x16_v1 | 8.05% | 2.94% |
vid_sasian_spice5_15s_9x16_v1 | 5.26% | 3.03% |
vid_sasian_bikini_10s_9x16_v1 | 4.76% | 2.94% |
vid_sasian_bikini_6s_9x16_v1 | 1.89% | 2.96% |
Per ad set: in_sasian_3up_purchase_d60 5.56% → 2.92%; utility_6s_purchase_d10 11.39% → 2.20%.
T3 India alone (one campaign, one geo): 6.61% → 2.81%, Fisher p = 1.34 × 10⁻³. T3's own complete days also differ from each other (χ² = 11.63, 3 dof, p = 0.0088).
Full window, d0 payer rate. Pooled rate 4.97%.
| Cut | Values | Test |
|---|---|---|
| Country (9 countries ≥20 installs) | see §7 | not significant, p = 0.5385 |
| Tier | T1 6.80% · T2 5.20% · T3 4.88% | not significant, p = 0.6758 |
| Generation | _260723 3.18% · _260725 5.07% | not significant, p = 0.3838 |
Per campaign:
| Campaign | Installs | Payers | d0 payer rate |
|---|---|---|---|
bailingxia_meituan_t3_cvr_260725 | 2,548 | 127 | 4.98% |
bailingxia_meituan_t2_cvr_260725 | 291 | 16 | 5.50% |
bailingxia_meituan_t3_cvr_260723 | 117 | 3 | 2.56% |
bailingxia_meituan_t1_cvr_260725 | 99 | 6 | 6.06% |
bailingxia_meituan_t2_cvr_260723 | 36 | 1 | 2.78% |
unknown | 600 | 6 | 1.00% |
| Installs | Payers | d0 payer rate | 95% CI | |
|---|---|---|---|---|
| Attributed | 3,096 | 154 | 4.97% | [4.26%, 5.80%] |
Unattributed (unknown) | 600 | 6 | 1.00% | [0.46%, 2.16%] |
Fisher p = 8.56 × 10⁻⁷.
Unattributed share of installs by day:
| Day | 07-24 | 07-25 | 07-26 | 07-27 | 07-28 | 07-29 |
|---|---|---|---|---|---|---|
| Share | 12.9% | 10.2% | 11.2% | 13.4% | 19.4% | 17.5% |
| Payers in that bucket | 0 | 0 | 0 | 2 | 0 | 0 |
Tracker coverage on backend payments: 63.4% carry a resolvable creative tracker.
Same cohort age (d0), Android only.
| Country | Our installs | Ours | 95% CI | Fleet installs | Fleet | Extraction |
|---|---|---|---|---|---|---|
| India | 3,073 | 4.17% | [3.51%, 4.93%] | 14,465 | 6.46% | 64% |
| Mexico | 292 | 5.82% | [3.67%, 9.12%] | 1,257 | 6.36% | 92% |
| United States | 77 | 6.49% | [2.81%, 14.32%] | 2,115 | 9.41% | 69% |
| Indonesia | 36 | 2.78% | [0.49%, 14.17%] | 3,250 | 3.78% | 73% |
| Canada | 26 | 7.69% | [2.14%, 24.14%] | 329 | 7.29% | 106% |
| Philippines | 22 | 4.55% | [0.81%, 21.80%] | 1,765 | 3.12% | 146% |
| United Arab Emirates | 20 | 5.00% | [0.89%, 23.61%] | 451 | 4.43% | 113% |
| United Kingdom | 35 | 0.00% | [0.00%, 9.89%] | 1,192 | 9.06% | — |
| Malaysia | 32 | 0.00% | [0.00%, 10.72%] | 1,396 | 4.51% | — |
India is 83% of our volume.
Installs by UTC hour block:
| Day | 00–16h | 17–23h | Evening share | Payer rate, 00–16 UTC only |
|---|---|---|---|---|
| 07-26 | 67 | 192 | 74.1% | 8.96% |
| 07-27 | 981 | 326 | 24.9% | 10.09% |
| 07-28 | 689 | 18 | 2.5% | 7.11% |
| 07-29 | 651 | 311 | 32.3% | 6.30% |
| 07-30 | 485 | in progress | — | 6.60% |
07-27 against 07-28 on identical hours: 1.42×, Fisher p = 0.036.
Conversion by hour of day, pooled 07-26 → 07-29: peak 17.28% at 07:00 UTC, trough 2.40% at 10:00 UTC. No single hour shows a step change.
| Question | What resolves it |
|---|---|
| Did our cost side move with the break? | Ads Manager export, ad level, 07-27 → 07-30. Not yet pulled. |
| Is the unattributed jump cause or symptom? | Backend payments export (account_id + tracker_name), which resolves payers to creatives. No copy in the repo. |
| Did a rotating cloak keyword land in this window? | Our campaign names carry keywords that rotate (meta_ads_setup.md). A mismatch routes real users to the wrong page, which reproduces finding 2's shape: installs hold, payer rate falls uniformly, attribution degrades. |
| Is the revenue damage as large as the payer damage? | Re-read the 07-28 and 07-29 cohorts at d3–d5 against §3. Not answerable before ~08-02. |
| Per-creative payer verdicts | Blocked: the largest arm holds 18 transactions, not 18 people, and no arm has reached ~16 payers in a day (creative_value_model.md §6). |
Adjust's cumulative_paying_users_conversion_rate_dN is unusable — it reads 805% at d7 on this app. It divides cumulative payers by cohort_size_dN, the count of users who have aged N days, and that denominator collapses on a young account:
| d0 | d3 | d7 | d14 | |
|---|---|---|---|---|
| Users aged that far | 3,696 | 802 | 22 | 3 |
| Adjust's cumulative rate | 4.33% | 21.95% | 804.55% | 5900.00% |
| Correct rate | 4.33% | 5.33% | 5.36% | 5.36% |
Every rate here is sum(paying_users_d0..dN) / cohort_size_d0 — fixed denominator, raw counts, no Adjust rate column read. The incremental column paying_user_conversion_rate_dN is also unsafe in an aggregated pull: it is a weighted mean of per-day rates, ~4% off the honest figure.
all_revenue_total_per_user_dN (ARPU) carries the same collapsing denominator, and it is the easier one to miss. Measured on this pull:
| Cohort | Age read | Adjust says | Denominator | Honest ARPU |
|---|---|---|---|---|
| 07-26 | d4 | $41.9560 | 4 of 259 | $0.6480 |
| 07-25 | d5 | $1.4365 | 108 of 236 | $0.6574 |
| 07-27 | d3 | $1.6428 | 627 of 1,307 | $0.7881 |
| 07-28 | d2 | $0.6221 | 442 of 707 | $0.3889 |
Recompute as ARPU_dN × cohort_size_dN / cohort_size_d0 before quoting any ARPU past d0. Reading the raw field produced a "2.4×–3.7× ARPU maturation" figure in an earlier draft of this report; the honest range is 1.35×–1.70×. ARPPU (revenue_total_per_paying_user_dN) is safe — its denominator is paying users, which grows rather than collapses (07-27: 11.43 → 12.36 → 12.32; 07-28: 16.83 → 16.18).
Cohort age is capped by the calendar. dN of install day D is calendar day D+N, so on 07-30 the 07-28 cohort has no d3 at all and its d2 is still running. Adjust returns 0 for those cells, and a cumulative sum turns the 0 into a flat line that reads exactly like "the cohort stopped converting." Blank every cell past a cohort's age before drawing any conclusion from a maturation table. A pooled payer-arrival profile has the same defect in a subtler form: young cohorts contribute a d0 and nothing else, which loaded the first bucket to 80.8% against 63.0% on mature cohorts only.
Repurchase is cumulative events over cumulative payers, so it can fall when a cohort adds payers faster than transactions (07-24 reads 2.83 at d3, 2.57 at d5). It is an average per payer to date, not a rate.
The day dimension is UTC; Ads Manager reports UTC−7. Verified — cohort day totals match UTC hour sums (1,307 / 707 / 962), not Pacific (1,188 / 629 / 829). Use asset_estimator.sources.window_for_pt_day() for any Meta join. Any comparison against a table on a different time base must reconcile this before the dates can be trusted.
A finished day is final. Re-pulling the 07-27 window two days later, every already-elapsed hour returned byte-identical; the only movement was the hour still in progress at the first pull. Same-day figures are provisional for the current hour only.
A part-day figure cannot be compared against a full-day one — the ~7× hour-of-day swing in §8 is the reason, and it is the binding constraint on any daily report.
export ADJUST_API_TOKEN=$(bwx field suite.adjust.com api_token | tail -1) # LAST line
python _runs/2026-07-29_payer_rate_analysis/pull.py
python _runs/2026-07-29_payer_rate_analysis/analyse.py # -> results.json
Wilson intervals throughout. Where a table had cells too thin for the standard chi-square, an exact (permutation) test was used instead.
For a recurring daily report, the cohort pull belongs in asset_estimator/ — it is the one piece here that would otherwise be rewritten every cycle, the failure asset_estimator/README.md § "Why it exists" exists to stop.