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.
| 2026-08-02 | 2026-08-03 | |
|---|---|---|
| spend | $278.28 | $445.83 |
| impressions | 28,955 | 213,053 |
| CPM | $9.61 | $2.09 |
| link clicks | 2,853 | 5,649 |
| CTR | 9.85% | 2.65% |
| installs (Meta) | 745 | 766 |
| click → install | 26.1% | 13.6% |
| cost per install | $0.374 | $0.582 |
| installs (ours) | 795 | 805 |
| 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 payers | 32 | 39 |
| within-day ARPU / ARPPU | $0.342 / $8.50 | $0.494 / $10.20 |
⚠ The blended delivery columns for 08-03 are unusable and must not be quoted. One ad (spill) bought 85.7% of the day's impressions, and 99.6% of its own impressions landed inside a single hour at a CPM of $0.52. That one hour drags account CPM to $2.09, CTR to 2.65% and click→install to 13.6%, none of which describes the day. Excluding that one ad:
| 08-02 | 08-03 blended | 08-03 less spill | |
|---|---|---|---|
| spend | $278.28 | $445.83 | $336.11 |
| impressions | 28,955 | 213,053 | 30,405 |
| CPM | $9.61 | $2.09 | $11.05 |
| CTR | 9.85% | 2.65% | 8.61% |
| click → install | 26.1% | 13.6% | 26.5% |
| cost per install | $0.374 | $0.582 | $0.485 |
On the honest row the day got dearer, not worse at converting. 5% more impressions at a 15% higher CPM, the same click-to-install rate (26.5% against 26.1%), and 30% more per install. Spend rose 21% while Meta-counted installs fell 7%, which is the whole of the move.
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.
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.
| hr | spend | impr | CPM | clicks | CTR | inst | clk→i | CPI | bkd$ | bROAS | wd$ | wROAS | wPay | coh$ | cROAS |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.00 | 0 | — | 0 | — | 3 | — | — | 8.75 | — | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| 1 | 0.00 | 0 | — | 0 | — | 1 | — | — | 60.76 | — | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| 2 | 0.00 | 0 | — | 0 | — | 0 | — | — | 41.69 | — | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| 3 | 0.00 | 0 | — | 0 | — | 1 | — | — | 26.21 | — | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| 4 | 5.65 | 515 | 10.97 | 58 | 11.26% | 10 | 17.2% | 0.565 | 6.47 | 1.14 | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| 5 | 19.64 | 2,009 | 9.78 | 189 | 9.41% | 38 | 20.1% | 0.517 | 10.73 | 0.55 | 4.99 | 0.25 | 1 | 4.99 | 0.25 |
| 6 | 24.63 | 2,471 | 9.97 | 222 | 8.98% | 61 | 27.5% | 0.404 | 26.32 | 1.07 | 20.06 | 0.81 | 3 | 20.06 | 0.81 |
| 7 | 27.85 | 2,804 | 9.93 | 242 | 8.63% | 54 | 22.3% | 0.516 | 25.87 | 0.93 | 36.63 | 1.32 | 4 | 40.19 | 1.44 |
| 8 | 30.14 | 3,420 | 8.81 | 266 | 7.78% | 62 | 23.3% | 0.486 | 23.95 | 0.79 | 78.62 | 2.61 | 5 | 78.62 | 2.61 |
| 9 | 29.74 | 3,726 | 7.98 | 294 | 7.89% | 77 | 26.2% | 0.386 | 38.96 | 1.31 | 29.98 | 1.01 | 3 | 48.72 | 1.64 |
| 10 | 29.54 | 3,203 | 9.22 | 250 | 7.81% | 61 | 24.4% | 0.484 | 19.71 | 0.67 | 14.71 | 0.50 | 2 | 14.71 | 0.50 |
| 11 | 9.08 | 1,046 | 8.68 | 99 | 9.46% | 35 | 35.4% | 0.259 | 52.18 | 5.75 | 49.72 | 5.48 | 4 | 49.72 | 5.48 |
| 12 | 0.29 | 33 | 8.79 | 4 | 12.12% | 4 | 100.0% | 0.073 | 15.56 | 53.67 | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| 13 | 18.84 | 1,590 | 11.85 | 111 | 6.98% | 25 | 22.5% | 0.754 | 21.60 | 1.15 | 20.41 | 1.08 | 3 | 26.31 | 1.40 |
| 14 | 107.17 | 182,805 | 0.59 | 3,000 | 1.64% | 61 | 2.0% | 1.757 | 21.96 | 0.20 | 0.00 | 0.00 | 0 | 19.16 | 0.18 |
| 15 | 8.10 | 823 | 9.84 | 76 | 9.23% | 21 | 27.6% | 0.386 | 38.22 | 4.72 | 5.63 | 0.70 | 1 | 5.63 | 0.70 |
| 16 | 14.19 | 1,080 | 13.14 | 94 | 8.70% | 24 | 25.5% | 0.591 | 87.44 | 6.16 | 23.20 | 1.63 | 2 | 23.20 | 1.63 |
| 17 | 16.03 | 1,267 | 12.65 | 103 | 8.13% | 24 | 23.3% | 0.668 | 22.86 | 1.43 | 5.76 | 0.36 | 1 | 5.76 | 0.36 |
| 18 | 18.31 | 1,181 | 15.50 | 107 | 9.06% | 32 | 29.9% | 0.572 | 28.87 | 1.58 | 25.77 | 1.41 | 4 | 34.94 | 1.91 |
| 19 | 21.44 | 1,263 | 16.98 | 121 | 9.58% | 33 | 27.3% | 0.650 | 18.88 | 0.88 | 32.52 | 1.52 | 1 | 32.52 | 1.52 |
| 20 | 18.58 | 1,141 | 16.28 | 116 | 10.17% | 40 | 34.5% | 0.465 | 9.16 | 0.49 | 0.00 | 0.00 | 0 | 6.84 | 0.37 |
| 21 | 19.93 | 1,046 | 19.05 | 129 | 12.33% | 34 | 26.4% | 0.586 | 23.22 | 1.17 | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| 22 | 13.66 | 859 | 15.90 | 95 | 11.06% | 36 | 37.9% | 0.379 | 48.37 | 3.54 | 18.10 | 1.33 | 3 | 21.77 | 1.59 |
| 23 | 13.02 | 771 | 16.89 | 73 | 9.47% | 29 | 39.7% | 0.449 | 31.59 | 2.43 | 31.59 | 2.43 | 2 | 40.92 | 3.14 |
| ALL | 445.83 | 213,053 | 2.09 | 5,649 | 2.65% | 766 | 13.6% | 0.582 | 709.35 | 1.59 | 397.69 | 0.89 | 39 | 474.05 | 1.06 |
Hour 14 is the whole anomaly of the day, in one line. $107.17 bought 182,805 impressions at a $0.59 CPM, against $8 to $19 in every other delivering hour, converted 2.0% of clicks to installs against 17% to 40% in every other hour that bought more than a hundred clicks, and returned zero within-day revenue from 61 installs. That one hour is 24.0% of the day's spend and 85.8% of its 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 is what the booked basis counts and the other two do not.
Hourly payer counts run 0–5, so an hourly ARPPU is one person's basket rather than a rate. 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 rather than payers: 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.
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 rather than paired with nothing. 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:
| metric | hours 2026-08-03 ran higher | hours it ran lower | sign test |
|---|---|---|---|
| CPM | 5 of 9 | 4 of 9 | p = 1.000 |
| CTR | 1 of 9 | 8 of 9 | p = 0.039 |
| click→install | 5 of 9 | 4 of 9 | p = 1.000 |
| CPI | 7 of 9 | 2 of 9 | p = 0.180 |
A sign test throws magnitude away and buys weight-free direction with it: it answers which way the day moved and never by how much.
One ratio separates, and it is CTR. It ran lower on 08-03 in 8 of the 9 shared hours, p = 0.039, which is a property of the day rather than of any one hour in it. CPM and click→install are coin flips on the unweighted count at p = 1.000 apiece, and CPI leans dearer in 7 of 9 hours without clearing 0.05. That last one is the shape a rising price takes on a nine-hour sample: visible in the count, not yet decidable. §4's pooled row reads click→install −62.8% at p = 0.000 over these same nine hours, which the hour count contradicts outright, and the disagreement is the point of running both.
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.
| hr | impressions | CPM | CTR | click→install | CPI |
|---|---|---|---|---|---|
| 08 | 1,512 → 3,420 | 8.79 → 8.81 | 10.98% → 7.78% | 17.5% → 23.3% | 0.458 → 0.486 |
| 09 | 4,266 → 3,726 | 8.46 → 7.98 | 8.74% → 7.89% | 22.0% → 26.2% | 0.440 → 0.386 |
| 10 | 4,119 → 3,203 | 10.05 → 9.22 | 9.42% → 7.81% | 24.7% → 24.4% | 0.431 → 0.484 |
| 11 | 3,119 → 1,046 | 8.89 → 8.68 | 9.43% → 9.46% | 27.2% → 35.4% | 0.347 → 0.259 |
| 13 | 2,752 → 1,590 | 11.32 → 11.85 | 11.12% → 6.98% | 23.5% → 22.5% | 0.433 → 0.754 |
| 14 | 2,578 → 182,805 | 9.88 → 0.59 | 10.78% → 1.64% | 28.4% → 2.0% | 0.322 → 1.757 |
| 15 | 2,670 → 823 | 9.09 → 9.84 | 10.19% → 9.23% | 24.6% → 27.6% | 0.362 → 0.386 |
| 16 | 3,024 → 1,080 | 9.11 → 13.14 | 10.35% → 8.70% | 22.4% → 25.5% | 0.393 → 0.591 |
| 17 | 1,543 → 1,267 | 8.71 → 12.65 | 9.07% → 8.13% | 30.7% → 23.3% | 0.313 → 0.668 |
Hour 14 owns the pooled row. In the pairing it runs 2,578 → 182,805 impressions, CPM 9.88 → 0.59 and CTR 10.78% → 1.64%, while the other eight shared hours move by ordinary amounts and in both directions. Of the 198,960 impressions §4's pooled row carries for this day, 182,805 are that single hour. It is the rejected spill build (DECISION_LOG.md #50), and any pooled comparison of these two days is mostly a report about it.
⚠ This table is a META-day cut on its spend and install columns. 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. Its revenue columns are bucketed on the UTC clock like the rest of the report, so the ratio columns cross a seven-hour offset. Read this table for mix, never for level against §1 or §2.
Top twelve by spend, all three measures.
| cc | spend | inst | CPI | booked | bROAS | within | wROAS | cohort@24 | cROAS |
|---|---|---|---|---|---|---|---|---|---|
| IN | 121.99 | 193 | 0.632 | 147.93 | 1.21 | 97.68 | 0.80 | 125.73 | 1.03 |
| US | 41.57 | 29 | 1.433 | 33.94 | 0.82 | 4.99 | 0.12 | 4.99 | 0.12 |
| GB | 16.69 | 24 | 0.695 | 16.90 | 1.01 | 16.90 | 1.01 | 16.90 | 1.01 |
| PH | 16.44 | 46 | 0.357 | 15.67 | 0.95 | 5.63 | 0.34 | 5.63 | 0.34 |
| MX | 14.55 | 27 | 0.539 | 11.42 | 0.78 | 11.42 | 0.78 | 14.82 | 1.02 |
| ID | 14.15 | 30 | 0.472 | 21.95 | 1.55 | 15.96 | 1.13 | 15.96 | 1.13 |
| MY | 13.86 | 16 | 0.866 | 11.74 | 0.85 | 11.74 | 0.85 | 11.74 | 0.85 |
| TR | 13.18 | 19 | 0.694 | 53.22 | 4.04 | 53.22 | 4.04 | 53.22 | 4.04 |
| FR | 13.08 | 19 | 0.688 | 31.15 | 2.38 | 31.15 | 2.38 | 31.15 | 2.38 |
| AR | 12.34 | 36 | 0.343 | 2.99 | 0.24 | 0.00 | 0.00 | 0.00 | 0.00 |
| AU | 8.94 | 8 | 1.117 | 19.76 | 2.21 | 0.00 | 0.00 | 0.00 | 0.00 |
| ES | 8.34 | 8 | 1.042 | 38.84 | 4.66 | 38.84 | 4.66 | 38.84 | 4.66 |
India is a quarter of the account day's buy at 24.4% of the META-day spend, and it is the only country here with a sample worth reading: 193 installs at $0.632, cohort@24h 1.03. The whole day carries 39 within-day payers at a mean of $10.20 each, so every country below India is a handful of baskets: Turkey's $53.22 and Spain's $38.84 are the largest of them and neither can be more than five or six people. Those ratios are directions and not magnitudes, and where a country carries a headline the largest single payer's share is what decides whether it means anything.
Thailand and Brazil are absent from the top of this table for a reason that is not performance. The account lost the ability to serve them, and the only cells in either country with more than a dollar of spend on this day belong to the incumbent campaign, which stopped buying before noon. See _runs/2026-08-04_e2_start_and_0803_report/th_br_what_its_worth.md.
Pooled over the 9 hours both days delivered in, on the UTC clock. Meta's instrument on both sides of every ratio.
| spend | impressions | CPM | clicks | CTR | installs | click→install | CPI | |
|---|---|---|---|---|---|---|---|---|
| 2026-08-02 | $240.39 | 25,583 | 9.40 | 2,530 | 9.89% | 618 | 24.43% | $0.389 |
| 2026-08-03 | $262.83 | 198,960 | 1.32 | 4,293 | 2.16% | 390 | 9.08% | $0.674 |
Pooling across hours is a mix comparison. It weights each hour by how much it delivered, so a day that bought differently across the clock can move these rows without any hour changing. The hour-by-hour pairing in the hourly section is the unweighted read of the same two days; where the two disagree, the mix moved.
The two reads disagree on click→install and agree on CTR. Pooled, click→install falls 62.8% at p = 0.000; counted hour by hour it rose in 5 of the 9 shared hours and the sign test reads p = 1.000. The pooled fall is hour 14 by itself, where 182,805 impressions converted 2.0% of their clicks, so it is not a statement about how the account converts and must not be quoted as one. CTR is the other case: pooled it falls 78.2%, and the unweighted count agrees that it fell, in 8 of 9 hours at p = 0.039. Even there the size belongs to hour 14 and only the direction survives both reads. Where the two agree, the day moved; where only the pooled row moves, the mix did.
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 to | metric | 08-02 | 08-03 | change | p | verdict |
|---|---|---|---|---|---|---|
| pooled | click → install | 25.63% | 29.37% | +14.6% | 0.055 | not separable |
| pooled | payer rate | 2.88% | 5.24% | +82.4% | 0.145 | not separable |
| pooled | CPI | $0.379 | $0.369 | better | — | |
| pooled | RPI | $0.338 | $0.479 | better | — | |
| pooled | ROAS | 0.89 | 1.30 | better | — | |
bodysuit | payer rate | 1.81% | 6.45% | +257.0% | 0.041 | BETTER |
bikini | payer rate | 7.94% | 3.23% | −59.4% | 0.252 | not separable |
pool5 | payer rate | 1.19% | 3.57% | +200.0% | 0.341 | not separable |
On matched hours the incumbent is flat to better. Every pooled term moves in the account's favour and none of them separates. The one result clearing 0.05 is bodysuit's payer rate, which rests on 3 payers against 8, is one significant result out of eight tests, and does not survive a Holm correction. It is not promoted here.
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:
| measure | 08-02 | 08-03 | moves after the day closes? |
|---|---|---|---|
| booked | $559.00 · 2.01 | $709.35 · 1.59 | settles a few hours after midnight, then fixed |
| within-day | $272.13 · 0.98 | $397.69 · 0.89 | never |
| cohort @ 24h | $360.61 · 1.30 | $474.05 · 1.06 | frozen once covered, 100% both days |
| cohort to date | $542.23 · 1.95 | $524.63 · 1.18 | rises ~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 on | 08-02's booked | 08-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. That is the entire gap between booked and within-day, and it is why a day whose spend is rising reads better on booked than on the measures that seal.
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:
| asset | delivering hours (UTC) | spend |
|---|---|---|
earner/bodysuit | 04:00 – 11:00 | $88.59 |
earner/bikini, earner/pool5 | 05:00 – 11:00 | $48.16, $39.52 |
E2/bikini, E2/mugshot | 12:00 – 23:00 | $48.91, $54.49 |
E2/spill | 13:00 – 22:00 (99.6% of its impressions inside hour 14) | $109.72 |
E2/bodysuit, E2/pool5 | 18: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.
No per-asset day-over-day comparison is available from the new campaign, because it did not exist on 08-02. §4's matched-hour block is the only matched-clock read here and it covers the incumbent's three creatives alone.
⚠ 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:
| asset | cc | spend | inst | CPI | within | wROAS | cohort@24 | cROAS |
|---|---|---|---|---|---|---|---|---|
E2/spill | IN | 23.69 | 4 | 5.923 | 0.00 | 0.00 | 0.00 | 0.00 |
E2/mugshot | IN | 23.56 | 19 | 1.240 | 0.00 | 0.00 | 0.00 | 0.00 |
E2/bikini | IN | 21.93 | 47 | 0.467 | 20.83 | 0.95 | 20.83 | 0.95 |
earner/bodysuit | IN | 19.59 | 50 | 0.392 | 59.57 | 3.04 | 81.87 | 4.18 |
E2/pool5 | IN | 9.52 | 17 | 0.560 | 0.00 | 0.00 | 0.00 | 0.00 |
E2/pool5 | US | 9.27 | 6 | 1.545 | 0.00 | 0.00 | 0.00 | 0.00 |
earner/bikini | IN | 9.12 | 29 | 0.314 | 5.76 | 0.63 | 5.76 | 0.63 |
E2/bodysuit | US | 8.82 | 6 | 1.470 | 0.00 | 0.00 | 0.00 | 0.00 |
E2/bodysuit | IN | 8.19 | 17 | 0.482 | 0.00 | 0.00 | 5.76 | 0.70 |
earner/pool5 | IN | 6.39 | 10 | 0.639 | 11.52 | 1.80 | 11.52 | 1.80 |
India is where the arms separate most visibly on cost. The same country bought installs at $0.392 for the incumbent's bodysuit and at $5.923 for spill and $1.240 for mugshot, a fifteenfold spread inside one geography.
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 consistent with a fresh-ad-set premium rather than with the creative; the third runs the other way by 12%, so the premium is a tendency on three pairs and not a measured rate.
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.
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.
Meta's instrument on both sides of every ratio. Our registrations never enter this table.
| asset | spend | impressions | CPM | clicks | CTR | installs | click→install | CPI |
|---|---|---|---|---|---|---|---|---|
E2/spill | $109.72 | 182,648 | 0.60 | 3,030 | 1.66% | 73 | 2.41% | $1.503 |
earner/bodysuit | $88.59 | 10,825 | 8.18 | 801 | 7.40% | 208 | 25.97% | $0.426 |
E2/mugshot | $54.49 | 3,394 | 16.05 | 287 | 8.46% | 69 | 24.04% | $0.790 |
E2/bikini | $48.91 | 4,375 | 11.18 | 374 | 8.55% | 102 | 27.27% | $0.480 |
earner/bikini | $48.16 | 4,670 | 10.31 | 452 | 9.68% | 128 | 28.32% | $0.376 |
earner/pool5 | $39.52 | 3,699 | 10.68 | 367 | 9.92% | 85 | 23.16% | $0.465 |
E2/pool5 | $32.28 | 1,809 | 17.84 | 215 | 11.89% | 53 | 24.65% | $0.609 |
E2/bodysuit | $24.16 | 1,633 | 14.79 | 123 | 7.53% | 48 | 39.02% | $0.503 |
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.
| asset | booked | bROAS (Meta) | within-day | wROAS | cohort@H | cROAS | payers | payer% | ARPU | ARPPU | largest payer |
|---|---|---|---|---|---|---|---|---|---|---|---|
E2/spill | $5.89 | 0.05 (0.11) | $5.89 | 0.05 | $25.05 | 0.23 | 1 | 1.3% | 0.075 | 5.89 | 100.0% |
earner/bodysuit | $340.67 | 3.85 (4.61) | $127.82 | 1.44 | $156.95 | 1.77 | 12 | 5.2% | 0.549 | 10.65 | 22.2% |
E2/mugshot | $10.70 | 0.20 (0.26) | $10.70 | 0.20 | $16.60 | 0.30 | 2 | 2.9% | 0.157 | 5.35 | 53.4% |
E2/bikini | $73.43 | 1.50 (1.65) | $73.43 | 1.50 | $80.51 | 1.65 | 9 | 8.6% | 0.699 | 8.16 | 23.0% |
earner/bikini | $159.56 | 3.31 (2.15) | $86.26 | 1.79 | $86.26 | 1.79 | 7 | 5.3% | 0.658 | 12.32 | 48.0% |
earner/pool5 | $43.34 | 1.10 (1.12) | $23.58 | 0.60 | $23.58 | 0.60 | 4 | 4.5% | 0.265 | 5.89 | 26.8% |
E2/pool5 | $44.60 | 1.38 (1.38) | $44.60 | 1.38 | $44.60 | 1.38 | 3 | 5.8% | 0.858 | 14.87 | 72.9% |
E2/bodysuit | $25.41 | 1.05 (1.05) | $25.41 | 1.05 | $40.49 | 1.68 | 1 | 2.1% | 0.529 | 25.41 | 100.0% |
The 16-payer bar (#37): any row above whose payer count is under 16 is a direction and never a magnitude.
⚠ This table is a META-day cut, not a UTC one. 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.
Why a row in B is readable or not. 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 asset bought a geography rather than earning a result.
| asset | spend | India % | US % | other % | US % of its revenue |
|---|---|---|---|---|---|
E2/spill | $110.05 | 21.5% | 4.5% | 74.0% | 0.0% |
earner/bodysuit | $57.11 | 34.3% | 3.0% | 62.7% | 0.0% |
E2/mugshot | $78.36 | 30.1% | 6.9% | 63.0% | 46.6% |
E2/bikini | $68.56 | 32.0% | 8.5% | 59.5% | 0.0% |
earner/bikini | $38.30 | 23.8% | 9.1% | 67.1% | 0.0% |
earner/pool5 | $30.95 | 20.6% | 6.8% | 72.6% | 0.0% |
E2/pool5 | $64.61 | 14.7% | 14.3% | 70.9% | 0.0% |
E2/bodysuit | $53.77 | 15.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.
Money is plotted per day across the run rather than hourly, because payers run 0-2 per asset per hour and an hourly ARPPU is one person's basket rather than a rate. 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.
META clock. The five new arms sat in one regime, $100/day each from 08-03 05:44 to 08-04 00:01 PT, so they are budget-matched to each other by construction and directly comparable. mix-neutral re-prices each arm's ROAS on the regime's pooled country mix while keeping its own cost and revenue efficiencies, which removes the geography difference between arms. Cells are matured to H=6.
| ad | regime | $/day | inst | spend | CPM | CTR | IN% | CPI | RPI | ROAS | mix-neutral |
|---|---|---|---|---|---|---|---|---|---|---|---|
bikini | E2-R1 | 100 | 160 | 69.8 | 11.32 | 8.82% | 34% | 0.436 | 0.490 | 1.12 | 1.08 |
bodysuit | E2-R1 | 100 | 111 | 56.2 | 12.58 | 6.90% | 17% | 0.506 | 0.423 | 0.84 | 0.80 |
pool5 | E2-R1 | 100 | 111 | 66.7 | 14.88 | 9.93% | 15% | 0.601 | 0.599 | 1.00 | 0.81 |
mugshot | E2-R1 | 100 | 95 | 80.9 | 16.97 | 8.64% | 22% | 0.852 | 0.179 | 0.21 | 0.22 |
spill | E2-R1 | 100 | 85 | 111.1 | 0.61 | 1.67% | 7% | 1.308 | 0.069 | 0.05 | 0.08 |
Re-pricing on the pooled mix moves no arm by more than 0.19 of ROAS and reorders none of them, so the ranking is not a geography artifact. Cost per install separates the arms across a threefold range ($0.436 to $1.308); their ROAS does not, with the three leading arms sitting between 0.84 and 1.12 on a handful of payers each.
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.
| arm | installs | payers | payer rate | ARPPU (to date) | ARPU @ H=24 |
|---|---|---|---|---|---|
earner/bodysuit | 233 | 13 | 5.6% | $12.89 | 0.674 |
earner/bikini | 131 | 9 | 6.9% | $10.95 | 0.658 |
earner/pool5 | 89 | 5 | 5.6% | $7.07 | 0.265 |
E2/bikini | 105 | 10 | 9.5% | $9.64 | 0.767 |
E2/bodysuit | 48 | 3 | 6.2% | $13.50 | 0.844 |
E2/pool5 | 52 | 3 | 5.8% | $14.87 | 0.858 |
E2/mugshot | 68 | 3 | 4.4% | $5.53 | 0.244 |
E2/spill | 79 | 2 | 2.5% | $12.53 | 0.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.
bodysuit's payer-rate result (p=0.041) is not promoted. Three payers against eight, one hit in eight tests, dead under Holm.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:
mugshot at $0.852 and spill at $1.308 against $0.436 to $0.601, and that ranking survives the mix-neutral re-pricing.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.
| measure | counts | moves after the day closes? |
|---|---|---|
| booked | revenue that arrived inside the UTC day, whatever day its payer installed | settles a few hours after midnight, then fixed. Meta's own number is this basis |
| within-day | people who installed that day and paid before the day closed | never. Sealed at midnight |
| cohort at H | that day's installs counted only to H hours of each person's own age. House horizon H=24, where both days are 100% covered | rises 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.
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%.