Payer rate and ARPU report — Vloom-GP, data through 2026-07-30

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.

1Daily figures by install day

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 dayInstallsAge todayd0 payer rated0 ARPUd0 ARPPUPayer rate at last complete age
07-24 (Fri)17162.92%$0.4160$14.235.26% (d5)
07-25 (Sat)23655.08%$0.3864$7.607.63% (d4)
07-26 (Sun)25945.41%$0.4790$8.868.11% (d3)
07-27 (Mon)1,30735.89%$0.6736$11.437.42% (d2)
07-28 (Tue)70722.26%$0.3808$16.832.40% (d1)
07-29 (Wed)96213.43%$0.2781$8.113.43% (d0)
07-30 (running)51003.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 dayd0 payer rate95% CI
07-242.92%[1.26%, 6.66%]
07-255.08%[2.93%, 8.68%]
07-265.41%[3.25%, 8.87%]
07-275.89%[4.74%, 7.30%]
07-282.26%[1.40%, 3.64%]
07-293.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⁻⁴.

2ARPU decomposition

ARPU = payer rate × ARPPU, exactly.

d0 payer rate× d0 ARPPU= d0 ARPU
07-275.89%$11.43$0.6736
07-282.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 dayd0d1d2d3
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*

3Cohort maturation

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 dayd0d1×d2×d3×d4×d5×d0 → last complete
07-242.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-255.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-265.41%7.34%1.36×7.72%1.05×8.11%1.05×8.11%*1.00×1.50× (d3)
07-275.89%7.04%1.19×7.42%1.05×7.57%*1.02×1.26× (d2)
07-282.26%2.40%1.06×2.40%*1.00×1.06× (d1)
07-293.43%3.53%*1.03×— (d0 only)

ARPU, recomputed on the same fixed denominator:

Install dayd0d1×d2×d3×d4×d5×d0 → last complete
07-24$0.4160$0.41601.00×$0.49061.18×$0.57291.17×$0.57291.00×$0.60661.06×1.46× (d5)
07-25$0.3864$0.42541.10×$0.56891.34×$0.65741.16×$0.65741.00×$0.6574*1.00×1.70× (d4)
07-26$0.4790$0.62121.30×$0.63421.02×$0.64801.02×$0.6480*1.00×1.35× (d3)
07-27$0.6736$0.76581.14×$0.78271.02×$0.7881*1.01×1.16× (d2)
07-28$0.3808$0.38891.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.

Is 07-28 + 07-29 actually different from the three days before?

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 atPost-breakPre-breakRatioFisher p
d0 — all six cohorts complete49 / 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 d117 / 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.

4By creative and ad set

Per creative, d0 payer rate:

Creative07-2707-28
vid_utility_6s_9x16_v111.39%2.20%
vid_sasian_bodysuit_10s_9x16_v18.05%2.94%
vid_sasian_spice5_15s_9x16_v15.26%3.03%
vid_sasian_bikini_10s_9x16_v14.76%2.94%
vid_sasian_bikini_6s_9x16_v11.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).

5By country, tier and generation

Full window, d0 payer rate. Pooled rate 4.97%.

CutValuesTest
Country (9 countries ≥20 installs)see §7not significant, p = 0.5385
TierT1 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:

CampaignInstallsPayersd0 payer rate
bailingxia_meituan_t3_cvr_2607252,5481274.98%
bailingxia_meituan_t2_cvr_260725291165.50%
bailingxia_meituan_t3_cvr_26072311732.56%
bailingxia_meituan_t1_cvr_2607259966.06%
bailingxia_meituan_t2_cvr_2607233612.78%
unknown60061.00%

6By attribution status

InstallsPayersd0 payer rate95% CI
Attributed3,0961544.97%[4.26%, 5.80%]
Unattributed (unknown)60061.00%[0.46%, 2.16%]

Fisher p = 8.56 × 10⁻⁷.

Unattributed share of installs by day:

Day07-2407-2507-2607-2707-2807-29
Share12.9%10.2%11.2%13.4%19.4%17.5%
Payers in that bucket000200

Tracker coverage on backend payments: 63.4% carry a resolvable creative tracker.

7Against the fleet benchmark

Same cohort age (d0), Android only.

CountryOur installsOurs95% CIFleet installsFleetExtraction
India3,0734.17%[3.51%, 4.93%]14,4656.46%64%
Mexico2925.82%[3.67%, 9.12%]1,2576.36%92%
United States776.49%[2.81%, 14.32%]2,1159.41%69%
Indonesia362.78%[0.49%, 14.17%]3,2503.78%73%
Canada267.69%[2.14%, 24.14%]3297.29%106%
Philippines224.55%[0.81%, 21.80%]1,7653.12%146%
United Arab Emirates205.00%[0.89%, 23.61%]4514.43%113%
United Kingdom350.00%[0.00%, 9.89%]1,1929.06%
Malaysia320.00%[0.00%, 10.72%]1,3964.51%

India is 83% of our volume.

8Delivery hours

Installs by UTC hour block:

Day00–16h17–23hEvening sharePayer rate, 00–16 UTC only
07-266719274.1%8.96%
07-2798132624.9%10.09%
07-28689182.5%7.11%
07-2965131132.3%6.30%
07-30485in progress6.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.

9Findings

  1. The break is 07-27 → 07-28. The 27th is the peak of the run on both payer rate and ARPU. The day-to-day variation is statistically real (§1), not sampling noise.
  1. The fall is in the payer rate only. ARPPU on 07-28 ($16.83) sits above the pre-break range, and repurchase is flat at 1.65 → 1.69 → 1.67 (§2). Fewer people paid; those who did paid normally and bought as often as before. Measures aimed at pricing, packaging or basket size address the part that did not change.
  1. 07-28 + 07-29 are statistically different from the three days before. Compared at d0, where every cohort is complete, the gap is 1.95× (p = 6.1 × 10⁻⁵); compared at d1, the deepest age available on both sides, it is 2.86× (p = 4.4 × 10⁻⁶). The three pre-break days show no difference from each other at d1 (p = 0.66), so using them as one baseline is fair (§3). The 07-28 cohort is also accruing more slowly — 1.06× from d0 against 1.19× for 07-27 and 1.36× for 07-26 — but on one day of accrual that is a weak signal, not a settled trend.
  1. Day-0 ARPU understates by roughly 1.4×–1.7×. On the only cohorts old enough to say — 07-24 (1.46× by d5), 07-25 (1.70× by d4) and 07-26 (1.35× by d3) — ARPU keeps accruing after install day but not dramatically (§3). Payer rate accrues on a similar scale. The 07-28 and 07-29 cohorts are too young to place on the curve, so the size of the revenue damage is not settled.
  1. Revenue cost so far. 707 installs on 07-28 returned $269 against $476 at the 27th's ARPU. Across the two complete post-break days, day-0 revenue is ~$478 below the 07-25→27 run rate, or ~$587 below the 27th alone.
  1. No dimension of how we split the buy explains it. Seven creatives spread 1.89%–11.39% on the 27th converge into 2.20%–3.03% on the 28th (§4); the same fall appears in both ad sets and inside a single campaign and geo. Over the full window country, tier, generation and campaign all fail to separate — every interval covers the pooled 4.97% (§5).
  1. About half the headline size was delivery timing. The 28th lost its evening block (2.5% share against 24.9%), and conversion swings ~7× by hour of day. Restricted to hours both days ran, the fall is 1.42× rather than 2.60×, and it persists ~35% below the 27th three days on (§8).
  1. Unattributed installs are the largest single effect in the data — 1.00% against 4.97%, p = 8.6 × 10⁻⁷ — and their share rose from 13.4% to 19.4% at the break with zero payers (§6). Either that traffic genuinely does not convert, in which case a rising share drags the blended rate down mechanically and part of finding 1 is mix; or attribution is losing real payers, in which case every per-arm rate here understates.
  1. India converts at 64% of the fleet benchmark and is the only country whose interval clears its benchmark (§7). At 83% of our volume it is the largest single gap in the report.

10Open items

QuestionWhat 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 verdictsBlocked: the largest arm holds 18 transactions, not 18 people, and no arm has reached ~16 payers in a day (creative_value_model.md §6).

11Measurement notes

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:

d0d3d7d14
Users aged that far3,696802223
Adjust's cumulative rate4.33%21.95%804.55%5900.00%
Correct rate4.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:

CohortAge readAdjust saysDenominatorHonest ARPU
07-26d4$41.95604 of 259$0.6480
07-25d5$1.4365108 of 236$0.6574
07-27d3$1.6428627 of 1,307$0.7881
07-28d2$0.6221442 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.

12Reproduction

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.

Internal — noindex. Not for distribution outside the team.