Daily campaign report — 2026-08-03, against 2026-08-02

Two campaigns bought inside this UTC day and they did not share a clock hour. The incumbent worldwide campaign delivered from 04:00 UTC until it was switched off at 11:20; a newly built campaign holding five ad sets, one creative each at $100/day, began delivering at 12:44 and ran to midnight. Together they spent $445.83 and bought 766 installs on Meta's count, 805 on ours; the report clock, the three revenue measures and regime are defined in the appendix.

1Overview

2026-08-022026-08-03
spend$278.28$445.83
impressions28,955213,053
CPM$9.61$2.09
link clicks2,8535,649
CTR9.85%2.65%
installs (Meta)745766
click → install26.1%13.6%
cost per install$0.374$0.582
installs (ours)795805
booked$559.00 · ROAS 2.01 (Meta $610.49 / 2.19)$709.35 · ROAS 1.59 (Meta $738.83 / 1.66)
within-day$272.13 · ROAS 0.98$397.69 · ROAS 0.89
cohort @ 24h$360.61 · ROAS 1.30 · 100% covered$474.05 · ROAS 1.06 · 100% covered
within-day payers3239
within-day ARPU / ARPPU$0.342 / $8.50$0.494 / $10.20

Cohort value — ARPU and ARPPU at d0, d3 and d7

Keyed on the INSTALL day and measured from each user's own install stamp: dN is their first (N+1) x 24 h. ARPU is Adjust's own series, the one the partner's dashboard reports; ARPPU is our payment ledger, because Adjust exposes no cumulative distinct-payer count. A horizon the window has not lived through yet is left empty rather than written as zero.

appARPU (d0)ARPU (d3)ARPU (d7)ARPPU (d0)ARPPU (d3)ARPPU (d7)installs
Vloom$0.5289$0.8934$1.1111$10.30$14.29$16.06896

⚠ The blended delivery columns are unusable. One ad, spill, took 85.7% of impressions, 99.6% of them inside one hour at $0.52 CPM. Excluding it:

08-0208-03 blended08-03 less spill
spend$278.28$445.83$336.11
impressions28,955213,05330,405
CPM$9.61$2.09$11.05
CTR9.85%2.65%8.61%
click → install26.1%13.6%26.5%
cost per install$0.374$0.582$0.485

Without spill, dearer at the same conversion rate. Impressions +5%, CPM +15%, click→install 26.5% against 26.1%, CPI +30%; spend +21%, Meta installs −7%.

All three revenue measures fall, so the direction is not a basis artifact. Booked 2.01 → 1.59, within-day 0.98 → 0.89, cohort@24h 1.30 → 1.06.

2Hourly, 2026-08-03

Delivery columns are Meta's on both sides; payer counts, ARPU and ARPPU are ours on both sides. The two install counts are never crossed. Booked sits on the payment hour; within-day and cohort sit on the install hour. Hours are UTC.

hrspendimprCPMclicksCTRinstclk→iCPIbkd$bROASwd$wROASwPaycoh$cROAS
00.000—0—3——8.75—0.000.0000.000.00
10.000—0—1——60.76—0.000.0000.000.00
20.000—0—0——41.69—0.000.0000.000.00
30.000—0—1——26.21—0.000.0000.000.00
45.6551510.975811.26%1017.2%0.5656.471.140.000.0000.000.00
519.642,0099.781899.41%3820.1%0.51710.730.554.990.2514.990.25
624.632,4719.972228.98%6127.5%0.40426.321.0720.060.81320.060.81
727.852,8049.932428.63%5422.3%0.51625.870.9336.631.32440.191.44
830.143,4208.812667.78%6223.3%0.48623.950.7978.622.61578.622.61
929.743,7267.982947.89%7726.2%0.38638.961.3129.981.01348.721.64
1029.543,2039.222507.81%6124.4%0.48419.710.6714.710.50214.710.50
119.081,0468.68999.46%3535.4%0.25952.185.7549.725.48449.725.48
120.29338.79412.12%4100.0%0.07315.5653.670.000.0000.000.00
1318.841,59011.851116.98%2522.5%0.75421.601.1520.411.08326.311.40
14107.17182,8050.593,0001.64%612.0%1.75721.960.200.000.00019.160.18
158.108239.84769.23%2127.6%0.38638.224.725.630.7015.630.70
1614.191,08013.14948.70%2425.5%0.59187.446.1623.201.63223.201.63
1716.031,26712.651038.13%2423.3%0.66822.861.435.760.3615.760.36
1818.311,18115.501079.06%3229.9%0.57228.871.5825.771.41434.941.91
1921.441,26316.981219.58%3327.3%0.65018.880.8832.521.52132.521.52
2018.581,14116.2811610.17%4034.5%0.4659.160.490.000.0006.840.37
2119.931,04619.0512912.33%3426.4%0.58623.221.170.000.0000.000.00
2213.6685915.909511.06%3637.9%0.37948.373.5418.101.33321.771.59
2313.0277116.89739.47%2939.7%0.44931.592.4331.592.43240.923.14
ALL445.83213,0532.095,6492.65%76613.6%0.582709.351.59397.690.8939474.051.06

Hour 14 is the whole anomaly. $107.17 at $0.59 CPM against $8–$19; click→install 2.0% against 17%–40% in hours past a hundred clicks; zero within-day revenue; 24.0% of spend, 85.8% of impressions.

The first four rows carry booked revenue against no spend. Those are hours in which nobody was buying but yesterday's and the day before's installs were still paying, which only the booked basis counts.

Hourly payer counts run 0–5, so an hourly ARPPU is one person's basket. Read the ALL row for level and the hours for shape only. The CPM path is the clean signal in this table, because its denominator is impressions: the incumbent's hours (04:00–11:00) run $7.98 to $10.97 with no trend, and the new campaign's hours climb from $11.85 at 13:00 to $15.50 and $19.05 across 18:00–23:00.

2026-08-05T10:30:27.056632 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 3 6 9 12 15 18 21 hour (UTC) 0 20 40 60 80 100 USD Spend by hour 0 3 6 9 12 15 18 21 hour (UTC) 0 25000 50000 75000 100000 125000 150000 175000 impressions Impressions and installs by hour impressions installs 0 10 20 30 40 50 60 70 80 installs (Meta Leads) The day's motion — whole account, 2026-08-03 (UTC)
The day's motion: spend by hour, and impressions against installs
2026-08-05T10:30:27.279759 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 4 8 12 16 20 hour (UTC) 2 4 6 8 10 12 CTR % CTR 0 4 8 12 16 20 hour (UTC) 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 USD per 1,000 impressions CPM 0 4 8 12 16 20 hour (UTC) 5 10 15 20 25 30 35 40 installs / clicks % Click → install 0 4 8 12 16 20 hour (UTC) 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 USD Cost per install Delivery by hour — whole account, 2026-08-03 (UTC)
CTR, CPM, click-to-install and CPI by hour, whole account

Against 2026-08-02, hour matched to hour

Only hours both days delivered in are compared. The diurnal shape is the largest confound in a day-over-day read on this account, so an hour one day is missing is dropped. This runs on the report clock, from the same loader as the table above, because spend, impressions, clicks and installs sit on Meta's delivery hour and restitch across two account days exactly.

Hours both days delivered in, on the UTC clock: 08, 09, 10, 11, 13, 14, 15, 16, 17. 2026-08-03 additionally delivered in 04, 05, 06, 07, 18, 19, 20, 21, 22, 23. 2026-08-02 additionally delivered in 00, 12. Only the shared hours are compared.

Counting which way each shared hour points, which needs no weighting and asks only for a direction:

metrichours 2026-08-03 ran higherhours it ran lowersign test
CPM5 of 94 of 9p = 1.000
CTR1 of 98 of 9p = 0.039
click→install5 of 94 of 9p = 1.000
CPI7 of 92 of 9p = 0.180

A sign test throws magnitude away and buys weight-free direction with it.

Only CTR separates: lower in 8 of 9 shared hours, p = 0.039. CPM and click→install are coin flips; CPI leans dearer without clearing 0.05.

The full hour-by-hour pairing, 2026-08-02 → 2026-08-03

Every shared hour, 2026-08-02 → 2026-08-03. All columns are Meta's instrument on both sides of each ratio. Revenue is deliberately absent: per-hour payer counts run 0-3, so an hourly revenue column would be one person's basket read as a rate.

hrimpressionsCPMCTRclick→installCPI
081,512 → 3,4208.79 → 8.8110.98% → 7.78%17.5% → 23.3%0.458 → 0.486
094,266 → 3,7268.46 → 7.988.74% → 7.89%22.0% → 26.2%0.440 → 0.386
104,119 → 3,20310.05 → 9.229.42% → 7.81%24.7% → 24.4%0.431 → 0.484
113,119 → 1,0468.89 → 8.689.43% → 9.46%27.2% → 35.4%0.347 → 0.259
132,752 → 1,59011.32 → 11.8511.12% → 6.98%23.5% → 22.5%0.433 → 0.754
142,578 → 182,8059.88 → 0.5910.78% → 1.64%28.4% → 2.0%0.322 → 1.757
152,670 → 8239.09 → 9.8410.19% → 9.23%24.6% → 27.6%0.362 → 0.386
163,024 → 1,0809.11 → 13.1410.35% → 8.70%22.4% → 25.5%0.393 → 0.591
171,543 → 1,2678.71 → 12.659.07% → 8.13%30.7% → 23.3%0.313 → 0.668

Hour 14 owns the pooled row: 182,805 of the 198,960 impressions §4 pools for this day. It is the rejected spill build (DECISION_LOG.md #50).

2026-08-05T10:30:27.528711 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 8 10 12 14 16 hour (UTC) 2 4 6 8 10 CTR % CTR 2026-08-02 2026-08-03 8 10 12 14 16 hour (UTC) 0 2 4 6 8 10 12 USD per 1,000 impressions CPM 8 10 12 14 16 hour (UTC) 5 10 15 20 25 30 35 installs / clicks % Click → install 8 10 12 14 16 hour (UTC) 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 USD Cost per install Delivery by hour — 2026-08-03 against 2026-08-02, shared hours only (UTC)
The same four ratios with the prior day laid over the day, shared hours only

3Country

2026-08-23T12:43:18.483707 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ IN US GB PH ID MY TR MX FR AR AU ES 0 20 40 60 80 100 USD delivery raked onto the report clock against two measured margins; revenue is the report day Spend against within-day revenue by country — 2026-08-03 spend within-day revenue
Spend against within-day revenue, by country
2026-08-23T12:43:18.533837 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ −0.04 −0.02 0.00 0.02 0.04 USD per install Cost per install by country — 2026-08-03 (report clock)
Cost per install by country

(i) The portfolio by country, 2026-08-03. On the report clock. Meta serves no hour x country grid, so each country cut is raked from its own Meta day onto UTC; our own columns were already there.

ccspendshareimpressionsCPMregistrations (ours)cost/regwithin-daywROASpayers
IN$108.1524.3%91,101$1.19216$0.501$97.680.9033
US$33.097.4%762$43.4123$1.439$4.990.154
GB$14.243.2%986$14.4318$0.791$16.901.191
PH$13.993.1%12,670$1.1042$0.333$5.630.402
ID$13.363.0%3,374$3.9642$0.318$15.961.204
MY$12.872.9%3,555$3.6219$0.678$11.740.911
TR$12.802.9%826$15.5027$0.474$53.224.163
MX$11.352.5%2,365$4.8019$0.597$11.421.016
FR$11.002.5%1,530$7.1915$0.733$31.152.832
AR$10.072.3%1,695$5.9429$0.347$0.000.001
AU$8.021.8%257$31.266$1.337$0.000.001
ES$7.901.8%1,645$4.8015$0.526$38.844.922

191 further countries are not listed, $188.99 between them (42.4% of this block).

Reconciliation, what is measured and what is fitted. Every per-country cell is an allocation across hours; every total is measured. B1 (UTC-7) $49.92 from Meta 2026-08-02 and $395.91 from Meta 2026-08-03, a measured UTC-day total of $445.83.

Absent from the table above, by name: Nomad Node, KBM1, HR1. Their spend is in every day-grain table; only their country split is missing.

(ii) The same cut per account, 2026-08-03.

B1

ccspendshareimpressionsCPMregistrations (ours)cost/regwithin-daywROASpayers
IN$108.1524.3%91,101$1.19216$0.501$97.680.9033
US$33.097.4%762$43.4123$1.439$4.990.154
GB$14.243.2%986$14.4318$0.791$16.901.191
PH$13.993.1%12,670$1.1042$0.333$5.630.402
ID$13.363.0%3,374$3.9642$0.318$15.961.204
MY$12.872.9%3,555$3.6219$0.678$11.740.911
TR$12.802.9%826$15.5027$0.474$53.224.163
MX$11.352.5%2,365$4.8019$0.597$11.421.016
FR$11.002.5%1,530$7.1915$0.733$31.152.832
AR$10.072.3%1,695$5.9429$0.347$0.000.001
AU$8.021.8%257$31.266$1.337$0.000.001
ES$7.901.8%1,645$4.8015$0.526$38.844.922

191 further countries are not listed, $188.99 between them (42.4% of this block).

Nomad Node — no country block: it delivered nothing on this day, a measured zero.

KBM1 — no country block: it delivered nothing on this day, a measured zero.

HR1 — no country block: it delivered nothing on this day, a measured zero.

The prior day, 2026-08-02, the same two tables.

(i) The portfolio by country, 2026-08-02. On the report clock. Meta serves no hour x country grid, so each country cut is raked from its own Meta day onto UTC; our own columns were already there.

ccspendshareimpressionsCPMregistrations (ours)cost/regwithin-daywROASpayers
IN$72.7126.1%13,199$5.51210$0.346$56.740.7825
US$14.815.3%317$46.7133$0.449$35.962.434
BR$14.475.2%1,162$12.4574$0.195$50.923.524
ID$12.544.5%1,832$6.8556$0.224$0.000.001
TR$9.143.3%471$19.4119$0.481$21.252.333
MY$7.182.6%825$8.7019$0.378$0.000.000
PH$6.352.3%1,431$4.4337$0.172$0.000.000
GB$6.192.2%184$33.626$1.032$0.000.000
IT$5.371.9%217$24.707$0.767$0.000.000
TH$5.151.9%584$8.8213$0.396$0.000.000
MX$5.111.8%458$11.1612$0.426$0.000.002
DE$4.921.8%126$39.009$0.547$0.000.000

178 further countries are not listed, $114.35 between them (41.1% of this block).

Reconciliation, what is measured and what is fitted. Every per-country cell is an allocation across hours; every total is measured. B1 (UTC-7) $7.13 from Meta 2026-08-01 and $271.15 from Meta 2026-08-02, a measured UTC-day total of $278.28.

Absent from the table above, by name: Nomad Node, KBM1, HR1. Their spend is in every day-grain table; only their country split is missing.

(ii) The same cut per account, 2026-08-02.

B1

ccspendshareimpressionsCPMregistrations (ours)cost/regwithin-daywROASpayers
IN$72.7126.1%13,199$5.51210$0.346$56.740.7825
US$14.815.3%317$46.7133$0.449$35.962.434
BR$14.475.2%1,162$12.4574$0.195$50.923.524
ID$12.544.5%1,832$6.8556$0.224$0.000.001
TR$9.143.3%471$19.4119$0.481$21.252.333
MY$7.182.6%825$8.7019$0.378$0.000.000
PH$6.352.3%1,431$4.4337$0.172$0.000.000
GB$6.192.2%184$33.626$1.032$0.000.000
IT$5.371.9%217$24.707$0.767$0.000.000
TH$5.151.9%584$8.8213$0.396$0.000.000
MX$5.111.8%458$11.1612$0.426$0.000.002
DE$4.921.8%126$39.009$0.547$0.000.000

178 further countries are not listed, $114.35 between them (41.1% of this block).

Nomad Node — no country block: it delivered nothing on this day, a measured zero.

KBM1 — no country block: it delivered nothing on this day, a measured zero.

HR1 — no country block: it delivered nothing on this day, a measured zero.

4Aggregate, both days

Pooled over the 9 hours both days delivered in, on the UTC clock. Meta's instrument on both sides of every ratio.

spendimpressionsCPMclicksCTRinstallsclick→installCPI
2026-08-02$240.3925,5839.402,5309.89%61824.43%$0.389
2026-08-03$262.83198,9601.324,2932.16%3909.08%$0.674

Pooling across hours weights each hour by what it delivered. The hourly pairing is the unweighted read of the same two days; where they disagree, the mix moved.

Click→install disagrees between the reads; CTR agrees. The pooled 62.8% fall is hour 14 alone; the 78.2% CTR fall survives both reads as a direction.

Held to the incumbent campaign's three creatives, on the ad account's own clock. Matched-hour delivery for a single creative has to be cut on the clock the exports are stamped in, so the hours below are the ad account's own UTC-7 hours. They land at 08:00–11:59 UTC inside both report days, so the block sits inside this report's day and inside the comparison day, but its hour labels are not the ones in §2, and its pooled rows are pooled over four Meta hours rather than the nine UTC hours above.

Delivering META hours — 08-02: [1–10, 21–23]; 08-03: [0–4]. Shared: [1, 2, 3, 4]. Maturity coverage at H=6 is 100% on both days. Only the incumbent campaign's three creatives existed on both days, so the comparison is held to them.

held tometric08-0208-03changepverdict
pooledclick → install25.63%29.37%+14.6%0.055not separable
pooledpayer rate2.88%5.24%+82.4%0.145not separable
pooledCPI$0.379$0.369better—
pooledRPI$0.338$0.479better—
pooledROAS0.891.30better—
bodysuitpayer rate1.81%6.45%+257.0%0.041BETTER
bikinipayer rate7.94%3.23%−59.4%0.252not separable
pool5payer rate1.19%3.57%+200.0%0.341not separable

On matched hours the incumbent is flat to better. Every pooled term moves in the account's favour and none of them separates.

This matters because the whole-day picture in §1 shows ROAS falling on all three bases. Both are true: the day as a whole delivered worse than 08-02, and the hours in which the same creatives ran on both days did not. The difference is composition. The report day bought twelve hours of a brand new campaign the comparison day has no counterpart for, at rising CPM, with one broken hour in the middle of it.

The three measures side by side, with the unbounded cohort figure below them for reference only:

measure08-0208-03moves after the day closes?
booked$559.00 · 2.01$709.35 · 1.59settles a few hours after midnight, then fixed
within-day$272.13 · 0.98$397.69 · 0.89never
cohort @ 24h$360.61 · 1.30$474.05 · 1.06frozen once covered, 100% both days
cohort to date$542.23 · 1.95$524.63 · 1.18rises ~72 h, reference only, never compared across days

Booked revenue split by the UTC day its payer installed, whose top row is the within-day figure:

payer installed on08-02's booked08-03's booked
the day itself$272.13 (48.7%)$397.69 (56.1%)
the day before$239.67 (42.9%)$109.64 (15.5%)
two days before$47.20 (8.4%)$137.54 (19.4%)
three days before—$58.74 (8.3%)
four days before—$5.74 (0.8%)

Inherited revenue fell from 51.3% to 43.9% of the day's bookings, which is the whole gap between booked and within-day.

2026-08-05T10:30:27.809664 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ booked within-day cohort @ 24h 0 100 200 300 400 500 600 700 USD 2.01 0.98 1.30 1.59 0.89 1.06 the number above each bar is that measure's ROAS against the same day's spend The three revenue measures, 2026-08-02 against 2026-08-03 (UTC) 2026-08-02 2026-08-03
The three revenue measures on both days, ROAS above each bar
2026-08-05T10:30:27.883889 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 2026-08-02 2026-08-03 0 100 200 300 400 500 600 700 USD the bottom segment IS the within-day figure: the same number seen twice Booked revenue by the day its payer installed (UTC) the day itself one day earlier two days earlier three days earlier four or more
Booked revenue by the day its payer installed

5Per ad set, hourly

Rows are labelled by asset. On the new campaign each ad set holds one ad holding one asset, so the ad-set row is the asset row; the incumbent's three creatives are three ads inside a single ad set, so those rows sit one level below it.

Full per-asset hourly grids are in _runs/2026-08-05_0804_settled/utc_2026-08-03/measures_out.txt. The shape that matters is when each asset delivered, because no two campaigns share a clock hour on this day:

assetdelivering hours (UTC)spend
earner/bodysuit04:00 – 11:00$88.59
earner/bikini, earner/pool505:00 – 11:00$48.16, $39.52
E2/bikini, E2/mugshot12:00 – 23:00$48.91, $54.49
E2/spill13:00 – 22:00 (99.6% of its impressions inside hour 14)$109.72
E2/bodysuit, E2/pool518:00 – 23:00$24.16, $32.28

The incumbent took 39.5% of the day's spend and 55.0% of its Meta-counted installs at a blended CPI of $0.419; the new campaign took 60.5% of spend and 45.0% of installs at $0.781. Held to within-day revenue the incumbent returned 1.35 and the new campaign 0.59; at cohort@24h, 1.51 against 0.77. Excluding spill, the new campaign's CPI is $0.588, still 40% above the incumbent's.

The new campaign has no per-asset day-over-day comparison, because it did not exist on 08-02; §4's matched-hour block covers the incumbent's three creatives alone.

2026-08-05T10:30:27.958518 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 2 4 6 8 10 12 14 16 18 20 22 hour (UTC) 5 10 15 20 CTR % CTR by hour — every asset, 2026-08-03 (UTC) E2/spill earner/bodysuit E2/mugshot E2/bikini earner/bikini earner/pool5 E2/pool5 E2/bodysuit
CTR by hour, one line per asset
2026-08-05T10:30:28.166182 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 2 4 6 8 10 12 14 16 18 20 22 hour (UTC) 0 10 20 30 40 50 60 installs / clicks % Click → install by hour — every asset, 2026-08-03 (UTC) E2/spill earner/bodysuit E2/mugshot E2/bikini earner/bikini earner/pool5 E2/pool5 E2/bodysuit
Click-to-install by hour, one line per asset
2026-08-05T10:30:28.264587 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 2 4 6 8 10 12 14 16 18 20 22 hour (UTC) 0.5 1.0 1.5 2.0 2.5 3.0 USD Cost per install by hour — every asset, 2026-08-03 (UTC) E2/spill earner/bodysuit E2/mugshot E2/bikini earner/bikini earner/pool5 E2/pool5 E2/bodysuit
Cost per install by hour, one line per asset
2026-08-05T10:30:28.052068 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 2 4 6 8 10 12 14 16 18 20 22 hour (UTC) 0 5 10 15 20 25 USD per 1,000 impressions CPM by hour — every asset, 2026-08-03 (UTC) E2/spill earner/bodysuit E2/mugshot E2/bikini earner/bikini earner/pool5 E2/pool5 E2/bodysuit
CPM by hour, one line per asset

6Per ad set × country

⚠ A META-day cut on spend and installs, like §3. Cells with spend over $1, ordered by spend; the full table is in _runs/2026-08-05_0804_settled/utc_2026-08-03/measures_out.txt. The head of it:

assetccspendinstCPIwithinwROAScohort@24cROAS
E2/spillIN23.6945.9230.000.000.000.00
E2/mugshotIN23.56191.2400.000.000.000.00
E2/bikiniIN21.93470.46720.830.9520.830.95
earner/bodysuitIN19.59500.39259.573.0481.874.18
E2/pool5IN9.52170.5600.000.000.000.00
E2/pool5US9.2761.5450.000.000.000.00
earner/bikiniIN9.12290.3145.760.635.760.63
E2/bodysuitUS8.8261.4700.000.000.000.00
E2/bodysuitIN8.19170.4820.000.005.760.70
earner/pool5IN6.39100.63911.521.8011.521.80

India is where the arms separate most on cost: earner/bodysuit $0.392 against E2/spill $5.923 and E2/mugshot $1.240, a fifteenfold spread inside one country.

India also holds the only three places where the same creative ran in both campaigns. bikini cost $0.314 for the incumbent and $0.467 for the new campaign, bodysuit $0.392 against $0.482, and pool5 $0.639 against $0.560. Two of the three favour the older ad set by 23% and 49%, which is what a fresh-ad-set premium looks like; the third runs the other way by 12%, so the premium is a tendency on three pairs and stops short of a measured rate.

2026-08-05T10:30:28.398124 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ E2/spill E2/mugshot E2/bikini E2/pool5 earner/bodysuit E2/bodysuit earner/bikini earner/pool5 0 20 40 60 80 100 % of that asset's spend Where each asset bought — share of its own spend by region, 2026-08-03 (META day) IN US GB PH MX ID other
Where each asset bought: share of its own spend by region
2026-08-05T10:30:28.501184 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ E2/spill E2/mugshot E2/bikini E2/pool5 earner/bodysuit E2/bodysuit earner/bikini earner/pool5 0 1 2 3 4 5 6 USD per install Cost per install by region — every asset, 2026-08-03 (META day) IN US GB PH MX ID
Cost per install by region, every asset
2026-08-05T10:30:28.592297 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ E2/spill E2/mugshot E2/bikini E2/pool5 earner/bodysuit E2/bodysuit earner/bikini earner/pool5 0 10 20 30 40 50 60 USD Within-day revenue by region — every asset, 2026-08-03 (META day) IN US GB PH MX ID
Within-day revenue by region, every asset

The three region charts are drawn from the same country export as the table above, so they carry its META-day caveat and each says so on its own title.

7Per ad set, aggregate, all three measures

The three tables below are emitted by report_tables.py and carry the same columns, in the same order, as every other report in this series, which is what lets one day be read against another. They are cut on the 2026-08-05 10:59 UTC payment cut. within-day is sealed at midnight and booked settles a few hours after it, so neither can move; cohort@24h is 100% covered on this day and is therefore frozen too. Rows are labelled by asset, on the same basis as §5.

A. Per asset — delivery

Meta's instrument on both sides of every ratio. Our registrations never enter this table.

assetspendimpressionsCPMclicksCTRinstallsclick→installCPI
E2/spill$109.72182,6480.603,0301.66%732.41%$1.503
earner/bodysuit$88.5910,8258.188017.40%20825.97%$0.426
E2/mugshot$54.493,39416.052878.46%6924.04%$0.790
E2/bikini$48.914,37511.183748.55%10227.27%$0.480
earner/bikini$48.164,67010.314529.68%12828.32%$0.376
earner/pool5$39.523,69910.683679.92%8523.16%$0.465
E2/pool5$32.281,80917.8421511.89%5324.65%$0.609
E2/bodysuit$24.161,63314.791237.53%4839.02%$0.503

B. Per asset — the three revenue measures

Ours on every column. Meta can express only booked, so it rides bracketed beside that column and never as a row. Payers are distinct people, never transactions. Cohort horizon H=24h, 100% covered on this day. Report clock UTC.

assetbookedbROAS (Meta)within-daywROAScohort@HcROASpayerspayer%ARPUARPPUlargest payer
E2/spill$5.890.05 (0.11)$5.890.05$25.050.2311.3%0.0755.89100.0%
earner/bodysuit$340.673.85 (4.61)$127.821.44$156.951.77125.2%0.54910.6522.2%
E2/mugshot$10.700.20 (0.26)$10.700.20$16.600.3022.9%0.1575.3553.4%
E2/bikini$73.431.50 (1.65)$73.431.50$80.511.6598.6%0.6998.1623.0%
earner/bikini$159.563.31 (2.15)$86.261.79$86.261.7975.3%0.65812.3248.0%
earner/pool5$43.341.10 (1.12)$23.580.60$23.580.6044.5%0.2655.8926.8%
E2/pool5$44.601.38 (1.38)$44.601.38$44.601.3835.8%0.85814.8772.9%
E2/bodysuit$25.411.05 (1.05)$25.411.05$40.491.6812.1%0.52925.41100.0%

The 16-payer bar (#37): any row above whose payer count is under 16 is a direction and never a magnitude.

C. Per asset — country mix

⚠ This table is cut on the META day, while every other table on this page is on the UTC clock. Meta serves no hour × country grid, so per-country delivery exists only on the ad account's own UTC-7 day and cannot be restitched. It is a seven-hour-offset window against tables A and B above; read it for mix, never for level against them.

The last column is the share of that asset's own within-day revenue that came from the United States: where it far exceeds the US spend share, the return is a property of the geography the asset bought.

assetspendIndia %US %other %US % of its revenue
E2/spill$110.0521.5%4.5%74.0%0.0%
earner/bodysuit$57.1134.3%3.0%62.7%0.0%
E2/mugshot$78.3630.1%6.9%63.0%46.6%
E2/bikini$68.5632.0%8.5%59.5%0.0%
earner/bikini$38.3023.8%9.1%67.1%0.0%
earner/pool5$30.9520.6%6.8%72.6%0.0%
E2/pool5$64.6114.7%14.3%70.9%0.0%
E2/bodysuit$53.7715.2%16.4%68.4%0.0%

⚠ The incumbent's booked ROAS is inflated by inheritance and the new campaign's is not. The incumbent stopped buying at 11:20 UTC but collected payments all day from earlier install days; earner/bodysuit's booked 3.85 against within-day 1.44 is that gap. The new campaign's arms have no prior cohort at all, so their booked and within-day figures are identical by construction. Compare the arms on within-day or cohort, never on booked.

No row in table B clears the 16-payer bar. earner/bodysuit tops the day at 12 within-day payers, so the whole per-asset revenue ranking on this day is a set of directions.

2026-08-05T10:30:28.700533 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 08-01 08-02 08-03 08-04 day (UTC) 0 1 2 3 4 5 6 7 8 payers / installs % Payer rate by day — every asset (UTC) earner/bodysuit earner/bikini E2/bikini E2/bodysuit E2/pool5 E2/mugshot earner/pool5 E2/spill E2/spill2
Payer rate by day, one line per asset
2026-08-05T10:30:28.797322 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 08-01 08-02 08-03 08-04 day (UTC) 0.0 0.2 0.4 0.6 0.8 1.0 1.2 within-day USD per install ARPU by day — every asset (UTC) earner/bodysuit earner/bikini E2/bikini E2/bodysuit E2/pool5 E2/mugshot earner/pool5 E2/spill E2/spill2
ARPU by day, one line per asset
2026-08-05T10:30:28.890837 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 08-01 08-02 08-03 08-04 day (UTC) 0 5 10 15 20 25 within-day USD per payer ARPPU by day — every asset (UTC) earner/bodysuit earner/bikini E2/bikini E2/bodysuit E2/pool5 E2/mugshot earner/pool5 E2/spill E2/spill2
ARPPU by day, one line per asset
2026-08-05T10:30:29.061875 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 08-01 08-02 08-03 08-04 day (UTC) 0.0 0.5 1.0 1.5 2.0 revenue / spend Within-day ROAS by day — every asset (UTC) earner/bodysuit earner/bikini E2/bikini E2/bodysuit E2/pool5 E2/mugshot earner/pool5 E2/spill E2/spill2
Within-day ROAS by day, one line per asset

Money is plotted per day across the run and never hourly, because payers run 0-2 per asset per hour and an hourly ARPPU is one person's basket. Hollow markers on the four charts above sit under the 16-payer bar, which on this day is every marker. Assets under 20 installs are left off the composite below and off §6's region charts; all eight assets on this day cleared that gate, so none of them is missing.

2026-08-05T10:30:29.175309 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ CTR click→install CPI payer rate * ARPU * wROAS * 0.0 0.2 0.4 0.6 0.8 1.0 normalised across the day (1.0 = best of the pack) * axis sits under the 16-payer bar on most days: direction only, never a level. Assets under 20 installs on the day are not plotted. Composite — every asset across every measure, 2026-08-03 E2/spill earner/bodysuit E2/mugshot E2/bikini earner/bikini earner/pool5 E2/pool5 E2/bodysuit
Composite: every asset across every measure, normalised across the day

The regime-matched, mix-neutral cut

META clock. The five arms held one $100/day regime, 08-03 05:44 → 08-04 00:01 PT. mix-neutral re-prices each arm's ROAS on that regime's pooled country mix; cells matured to H=6.

adregime$/dayinstspendCPMCTRIN%CPIRPIROASmix-neutral
bikiniE2-R110016069.811.328.82%34%0.4360.4901.121.08
bodysuitE2-R110011156.212.586.90%17%0.5060.4230.840.80
pool5E2-R110011166.714.889.93%15%0.6010.5991.000.81
mugshotE2-R11009580.916.978.64%22%0.8520.1790.210.22
spillE2-R110085111.10.611.67%7%1.3080.0690.050.08

The mix-neutral re-pricing moves no arm more than 0.19 of ROAS and reorders none, so geography does not drive this ranking.

Install-cohort ARPU and ARPPU, at a fixed horizon

Install days on the UTC clock, installs and payers on our own records. All eight arms are 100% covered at H=24 on this day. The payer rate and ARPPU columns are to-date figures and grow with a cohort's age, so they describe this day and may not be read across days; the H=24 column is the one that is comparable.

arminstallspayerspayer rateARPPU (to date)ARPU @ H=24
earner/bodysuit233135.6%$12.890.674
earner/bikini13196.9%$10.950.658
earner/pool58955.6%$7.070.265
E2/bikini105109.5%$9.640.767
E2/bodysuit4836.2%$13.500.844
E2/pool55235.8%$14.870.858
E2/mugshot6834.4%$5.530.244
E2/spill7922.5%$12.530.317

The three incumbent creatives are the only ones with a prior day at the same horizon and the same coverage. At H=24, bodysuit moved 0.449 → 0.674 and bikini 0.407 → 0.658, while pool5 fell 0.499 → 0.265. Two of three up, one down, on 5 to 13 payers each. The new campaign's mugshot and spill sit at 0.244 and 0.317, below every other arm on the account, and they are the same two arms that sit last on cost per install.

8Caveats

9What would settle the open questions

10What this hands to the five-arm test

The five new ad sets became the arms of a randomised test when the budget-matched regime ended at 08-04 00:01 PT. This day is their observational baseline:

11Appendix — the clock, the measures, and regime

The report day is a UTC day. Meta stamps its exports in the ad account's own zone, UTC-7, so this day is Meta's 08-02 17:00–23:59 stitched onto Meta's 08-03 00:00–16:59, and every delivery figure above is restitched across those two account days.

Three revenue measures run through every table and are never mixed.

measurecountsmoves after the day closes?
bookedrevenue that arrived inside the UTC day, whatever day its payer installedsettles a few hours after midnight, then fixed. Meta's own number is this basis
within-daypeople who installed that day and paid before the day closednever. Sealed at midnight
cohort at Hthat day's installs counted only to H hours of each person's own age. House horizon H=24, where both days are 100% coveredrises until every install has lived H hours

All three are read on our own payment records; Meta's figure appears bracketed beside the booked column and never as a row of its own.

The instrument gate runs on the META clock, because Meta's conversion value sits on its conversion hour and is the one column that cannot be honestly restitched into a UTC day. Held there, our records read 0.98 of Meta's booked value on 08-03 and 0.91 on 08-02, both inside the documented 0.91–1.06 band. The bracketed Meta figures in §1's table are shown for traceability, and the ratio between them is not a valid check on this clock.

A regime is a stretch over which an ad set's daily budget did not change. It matters because on this account the budget is a geography dial: raising it buys wider, cheaper countries, so two creatives measured across a budget change are compared on different audiences.

This day sat in two regimes that do not overlap in time. The incumbent campaign held a flat $500/day through 11:20 UTC, the same regime it held for the whole of 08-02, which is what makes the two days comparable at all. The new campaign then ran five ad sets at a flat $100/day each from 12:44 UTC to midnight, a regime with no counterpart on the comparison day. Nothing spans both, so no cross-regime comparison is attempted in this report.

12Reproduce

CFG=_runs/2026-08-05_0804_settled/run_config.json          # tz = UTC
MET=_runs/2026-08-05_0804_settled/run_config_meta.json     # tz = META

# 1 — the three revenue measures, at campaign / hourly / country / asset
PYTHONIOENCODING=utf-8 python -m ad_ops.measures --config $CFG --day 2026-08-03 --prev 2026-08-02

# 1b — the instrument gate, which is only valid on Meta's clock
PYTHONIOENCODING=utf-8 python -m ad_ops.measures --config $MET --day 2026-08-03 --prev 2026-08-02

# 2 — matched clock hours at a fixed horizon, with two-proportion tests (META clock)
PYTHONIOENCODING=utf-8 python -m ad_ops.day_compare --config $MET \
  --today 2026-08-03 --prev 2026-08-02 --h 6 \
  --ads "ww_bikini_10s,ww_bodysuit_10s,ww_pool5_15s" \
  --campaign "bailingxia_meituan_ww_cvr_260730"

# 3 — regimes, horizons, delivery overlap, the decidability gate (META clock)
PYTHONIOENCODING=utf-8 python -m ad_ops.asset_estimator hourly \
  --meta _runs/2026-08-04_e2_start_and_0803_report/exports/ads_hourly_aug3_settled.csv \
         _runs/2026-08-05_0804_settled/exports/ads_hourly_aug4_settled.csv \
  --lum _runs/2026-08-05_0804_settled/lum \
  --fx _runs/2026-08-02_today_read/fx_rates.json \
  --ads "ww_bikini_10s,ww_bodysuit_10s,ww_pool5,ww_mugshot,ww_spill" \
  --campaign "bailingxia_meituan_ww_cvr_260802" --horizon 6

# 4 — install-cohort ARPU and ARPPU, to date and at fixed horizons
PYTHONIOENCODING=utf-8 python -m ad_ops.cohort_arpu --config $CFG \
  --days 2026-07-31,2026-08-01,2026-08-02,2026-08-03

# 5 — §7's three standing tables, §2's matched-hours pairing, §4's pooled funnel,
#     and the nineteen standing charts
PYTHONIOENCODING=utf-8 python -m ad_ops.report_tables --config $CFG \
  --day 2026-08-03 --prev 2026-08-02
PYTHONIOENCODING=utf-8 python -m ad_ops.report_charts --config $CFG \
  --day 2026-08-03 --prev 2026-08-02 \
  --days 2026-08-01,2026-08-02,2026-08-03 --out ad_ops/figures/2026-08-03 \
  --md _runs/2026-08-05_0804_settled/chartblock_2026-08-03.md --relpath figures/2026-08-03

report_tables --prev emits §2's matched-hours pairing and §4's pooled funnel as well as §7's three standing tables. report_charts writes all nineteen charts and a per-section block of image links.

The report clock is UTC and the ad account's is UTC-7, so a UTC pull needs one export more than a Meta-day pull: the previous Meta day's hourly file, every time. This day is stitched from ads_hourly_aug2_settled.csv hours 17–23 and ads_hourly_aug3_settled.csv hours 00–16, and the comparison day from ads_hourly_aug1_settled.csv hours 17–23 and ads_hourly_aug2_settled.csv hours 00–16. The estimator additionally loads ads_hourly_aug4_settled.csv so that post-midnight installs are not carried back into the last delivering cell of 08-03.

Meta exports were pulled after each day closed and settled, and each is verified by its own content, row count and the window read off Reporting starts / Reporting ends, never by filename. Country data comes from ads_country_day_jul1_aug5.csv, which is per Meta day and is the reason §3, §6, table C and the region charts cannot follow the report clock.

Payment records: Telegram exports of both notification channels, parsed with ad_ops/lum_notifications/parse_export.py. Payment data cut 2026-08-05 10:59 UTC, at which point both days' cohorts are 100% covered at H=24; ages at the cut run 35.0–58.1 h on 08-03 and 61.4–82.9 h on 08-02.

Selection is by Ad ID throughout, never by ad or ad-set name. The two campaigns run creatives with byte-identical names and a name filter over-attributes by about 70%.

Internal — noindex. Not for distribution outside the team.