Performance marketing for AI-era growth – backed by models, not gut feeling.

Supporting document for the Unit Economics Estimator (v1.1, September 2026). Each entry: what is computed → formula → why → what was rejected → status. Every number is the one in the calculator's code (constants CONFIG, GEO, VERT, PLAT / PLATW, MAI, TRIALLEN, BASE, COST_SCEN, stage tables A2A_STAGES / W2W_STAGES, LTV_FIELDS); the source of each benchmark is captioned on the field inside the tool. The dated decision log is at the end.

Notation: [B] benchmark · [E] estimate · [A] assumption · "decision DD.MM" – the date the choice was fixed.

0. Architecture: two modes for every field

What. Every numeric field lives either as a benchmark (picked by vertical × geo × scenario) or as my data (typed in, shown in blue).

The effective-value rule. A typed value is used as is: seasonality and the optimization-event discount are not applied to a typed CPM; the paid-traffic factor and the platform factor are not applied to a typed store CVR; the intent factor of the optimization event and the platform factor are not applied to a typed paywall→trial; geo and trial length are not applied to a typed trial→paid; the AI factor and the price ramp are not applied to typed retention anchors.

Why. An observed number already contains the user's reality: their season, their optimization event, their platform. Applying a modifier on top counts it twice.

Rejected. "Typed value = base, modifiers on top." Convenient for what-ifs ("and with AEO?"), but it breaks on the main use case – the user types their actual CPM from Ads Manager, and that CPM is already an AEO price.

Consequence. On the Funnel tab a typed value makes the iOS and Android columns identical at that stage – correct, not a bug.


1. Scenarios = benchmark percentiles

Formula. The scenario's position on the P25 → median → P75 scale: Pessimistic 0, Conservative 0.3, Reasonable 0.5, Aspirational 1; linear interpolation between nodes.

pick(t, s):  x ≤ 0.5 → P25 + (med − P25)·x/0.5;   x > 0.5 → med + (P75 − med)·(x − 0.5)/0.5

Cost fields run the other way (decision 4 Sep 2026). CPM (geo table, web table) takes the mirrored position: Pessimistic → P75 (an expensive auction), Conservative → between the median and P75, Aspirational → P25.

pickCost(t, s) = pick(t, mirror(s)),   mirror: p25→p75, p40→p60 (0.7), med→med, p75→p25

Why. The word "pessimistic" promises the user "everything against you". A P25 cost is cheap, i.e. in your favor. Before the fix Pessimistic took CPM $12 against a median of $16, and Aspirational took $23: the preset partly canceled itself, and a reader who knows that a P25 CPM is good caught the model contradicting itself.

Rejected. (b) Keep CPM at the median in every scenario and move only conversions and retention – the argument being "the market price is not luck, it is typed in". Rejected: seasonality and the optimization event already move CPM through their own selectors, and a scenario must be one movement – "every benchmark to the worse/better side" – or it needs a paragraph of caveats.

The scenario step – P25 / P75 of every stage – is a decision, not an oversight (4 Sep 2026). The preset moves each of the ~10 multiplied stages to its quartile. The product of ten P25s is not "a P25 app": if the stages were independent the result would sit somewhere at P1–P5 of the distribution of outcomes; in practice the stages are positively correlated (a good team is good everywhere) and the result is less extreme – but still more extreme than a quartile. Numbers on the default H&F × NA (hard-paywall base, AEO): cost per subscriber $802 / $182 / $79.51 / $9.42 (Pessimistic / Conservative / Reasonable / Aspirational), net LTV $55 / $60 / $63 / $71. The spread lives almost entirely on the CPA side – eight multipliers there; the LTV side moves ±13%.

How to read it: Pessimistic = the lower quartile at every funnel stage, Aspirational = the upper quartile; not "a bad year" and "a good year" but "a weak team end-to-end" and "a strong team end-to-end". That is exactly how the selector and the how-to caption it.

Rejected, and why: - Narrow the stage step to P35/P65 so that the result is closer to the quartiles. Rejected: then no number in the fields would match the public reports (RC, Adapty, Interact publish the median and the quartiles) – and matching the report is the first thing a reader checks, the main pillar of trust. Besides, P35/P65 is our invention; it has no source. - Compute scenarios as percentiles of the outcome (Monte Carlo over correlations). Rejected for v1: it needs correlations between stages that no report publishes; it would be [A] stacked on [A]. - Let the scenario move unsourced pairs (the MAI price/intent discount). Rejected 4 Sep 2026: the pair ×0.4/×0.4 [E] is fixed; otherwise a pure assumption would be added to the spread in both directions.

What the user does with the spread: the preset is a starting point, not a forecast. A typed value takes that stage out of the preset; after three or four numbers of your own (CPM, CTR, install→trial, trial→paid) the spread collapses to the LTV side. Sensitivity shows which of the remaining stages holds the spread.


2. CPM

CPM_eff = pickCost(geo base, scenario) × platform × seasonality × optimization-event premium

Why the CPM base counts as AEO-basis, not MAI-basis (decision 4 Sep 2026). The Lebesgue panel is purchase-optimized e-commerce campaigns – a "deep event", like AEO. The previous version treated $16 as the MAI price and stacked an AEO premium of ×4 on top → $64 per thousand impressions in the US, above any published app panel (RocketShip HQ: blended CPM by category $5.40–17.50). The final check: the modeled paid CPI for H&F at medians ($8.26 iOS) lands on an independent app-install benchmark (RocketShip $7.80) – with AEO-basis, not with ×4.

Why CPM and not CPC/CPI as the input. We pay for impressions; everything below is conversions, each with its own benchmark and its own owner on the team. With CPI as the input you cannot show which stage is broken.

Rejected. A separate "my CPI/CPT" input (a practitioner has exactly those). Open for v2: an "I know my CPI" input with CPM back-solved. For now: typed CPM + typed stages.


3. From impression to install (a2a)

CPC  = CPM / 1000 / CTR
CPI_paid = CPC / (click→store × storeCVR_eff)
storeCVR_eff = storeCVR(category, store) × paid-factor          – unless typed
CPI  = CPI_paid / (1 + organic uplift)                          – blended CPI

Why organic sits inside CPI rather than on its own line. That is how UA reports count it ("CPI including organic"), and it is the honest way for payback: every install the paid traffic brought returns money. Assumption: organic installs convert to trial like paid ones – the difference is not modeled.


4. From install to trial

install→trial = install→paywall × paywall→trial_eff × AI factor
paywall→trial_eff = paywall→trial × AEO uplift × platform        – unless typed
CPT = CPI / install→trial

Why derived rather than benchmarked. There is no per-unique-view paywall benchmark in public data: Adapty's 1.35% is per impression, with repeats – unusable. What does exist is RC's reliable download-to-trial composite by vertical and geo. Before, a fixed H&F × NA figure 8/12.3/18% stood for every vertical and geo; as a result the model's own cross-check ("product of stages vs the RC composite") fired on untouched defaults in 25 of 36 combinations, and the CPA for TR/LatAm/IN-SEA was understated by half.

Rejected. Applying the geo factor and the vertical to install→paywall instead of paywall→trial. Superwall's 56% median has no geo split, RC's composite does; therefore the whole vertical-and-geo difference sits, by construction, in the paywall.

Benchmark base for install→trial: hard-paywall apps (decision 4 Sep 2026, selector in Setup). RC's category medians mix all access models, and most apps in the panel are freemium, where a minority of installs ever see the paywall. RC 2026: hard-paywall apps convert 10.7% of downloads to paying (top quartile above 20%), freemium – 2.1% [B]; that is above even the top quartile of the best categories across all apps (H&F 6.2%). The tool models hard paywalls only, so the default base shifts RC's install→trial band one quartile up: P25 := panel median, median := panel P75, P75 := P75 × (P75 ÷ median). H&F: 5.0 / 6.9 / 16% → 6.9 / 16 / 37%. The fact is [B], the size of the shift is [E]. The "All apps" selector returns the raw panel band.

Why "one quartile" and not "×5 per RC": 10.7% against the global 2.0% download→paid would put ×5.35 on the composite and H&F download→paid at 15.5% – above the category's P90; RC's hard-paywall group is skewed by category (utilities, AI-photo apps with a day-0 purchase). "The panel's P75 as the hard-paywall median" is a conservative lower estimate that RC's 10.7% clears with room to spare. Reality check: the median CPT for H&F × NA becomes $33 (on the panel band – $77), cost per subscriber $79.51, ROAS 0.80 – inside the corridor UA practitioners recognize; "All apps" returns the panel band: $184 / 0.34.

Rejected: (a) keep the panel median and explain it – the "ROAS 0.33" headline stays a target for anyone who has read RC; (b) apply ×5 literally – over-optimistic and contradicts the category quartiles; (c) introduce a separate access-model cut per vertical – RC has no such data.

Cross-check (the safety catch). The product of stages (÷ the intent factor of the optimization event, i.e. the organic equivalent) is compared with RC install→trial (selected base) × geo factor × platform paywall factor [× AI]; a gap >×1.5 raises a yellow warning. On untouched defaults the ratio is exactly 1.0 for every platform, both bases, all verticals × geos × scenarios (self-test); the warning reacts only to typed values. Earlier versions fired on defaults (fixed paywall→trial; then the AEO uplift; then the platform factor) – each time the comparison was fixed, not the warning silenced.


5. From trial to subscriber

with trial:  CPA(sub) = CPT × trial share / trial→paid
no trial:    CPA(sub) = CPI / (install→paywall × paywall→trial_eff × 0.4)
no trial:  subscribers / paywall view = paywall→trial_eff × 0.4
with trial:                            = paywall→trial_eff × trial→paid / trial share
break-even: the trial pays off ⇔ trial→paid > 0.4 × trial share  (≈ 36% at a 90% share)

Why 0.4 and not Adapty's 0.6. The only public source is Adapty's cross-panel per-impression comparison: a paywall without a trial gets 0.82% purchases against 1.35% trial starts on a paywall with one – ratio 0.6. That is not a counterfactual "same app, trial removed" but a comparison of different apps: those living without a trial are self-selected – direct purchase works for them (low price, instant value). So 0.6 is a ceiling. Applied literally, it made no-trial beat the trial by 43% on subscribers in every vertical (independent of the benchmark base: the comparison is on the same paywall) – including H&F, where Adapty finds the opposite on LTV. A/B practice for trial vs no-trial lands at 0.3–0.5; the midpoint is used.

Why a multiplier on trial starts, not on payers. What practitioners observe most stably is exactly the ratio of "direct purchases to trial starts on the same paywall" – people say yes to "free" several times more readily. Then the "trial or not" verdict is decided by trial→paid – a [B] quantity by vertical and geo – not by the toggle itself: H&F median 37.7% → the trial wins by 5%; Productivity 30% → no-trial wins by 20% (consistent with Adapty's "direct beats trial" for Productivity); H&F P75 51% → trial ×1.35. The calculator prints the break-even and the verdict in the explain line in both modes.

Rejected. (a) 0.6 on the paying share (3.1% direct purchases) – no-trial always loses, contradicting Productivity/Lifestyle. (b) Parity on payers (k = 1) – an honest "we don't know", but the toggle becomes useless, and "do I need a trial" is one of the most frequent questions. (c) Keep 0.6 with a warning – a warning does not fix the verdict.

Not modeled. The LTV difference between trial and direct cohorts (Adapty: Productivity direct +16%; in H&F trial cohorts are worth more): in v1 both cohorts sit on one curve, with a hint left for Productivity/Lifestyle. A self-test checks that the model's verdict matches the break-even rule.


6. Optimization event: AEO is the base, MAI is a discount (decision 4 Sep 2026)

Why it was flipped from "MAI base, AEO ×4/×4" to "AEO base, MAI ×0.4/×0.4". Arithmetically the parity is the same, the level is not: the previous version gave an AEO CPM of $64 in the US (above any app panel) and, worse, broke on the hard-paywall base – an uplift of ×4 on a paywall converting at 29% gave 114% (the cap destroyed the parity). Tying the benchmarks to their real basis (AEO/organic) removes both, and CPI lands on RocketShip.

Rejected. (a) MAI as default – "nobody runs MAI for subscriptions in 2026". (b) Claiming "AEO is worse/better than MAI by X%" – no source with either sign. (c) Uplift via odds or with saturation – the parity holds only up to the cap, harder to explain, still no source.

Why the intent factor sits on the paywall and not on trial→paid. Conservative and checkable: the optimization event changes who reaches the paywall; an effect on trial-to-paid conversion is not confirmed by anything public.


7. w2w (quiz funnel, hard paywall at the end of the quiz)

CPA(sub) = CPC / (click→LP × LP→quiz start × quiz finish × email × paywall→checkout_eff × checkout completion_eff)

Cost per quiz start (decision 4 Sep 2026). The "Modeled CPI / CPC" KPI in w2w = CPC ÷ (click→LP × LP→quiz start) – the cost of a quiz start, as captioned. Before, the formula also divided by quiz completion (giving the cost per quiz completion, $5.15 instead of $3.09 on the default), and the budget line understated the number of quizzes by 40%. Why quiz start and not completion: the start is the first event visible in the pixel and the one lead/checkout campaigns are optimized against; completion is already mixed with quiz length. A self-test holds the formula.


8. LTV M13 – the payment schedule

What. For each plan – a monthly schedule of one subscriber's payments, months 0–12; blended by plan shares; net after VAT and the fee.

Blended[m] = Σ share_i × schedule_i[m] / Σ shares × (1 + upsell)
schedule_i[0] = intro_i × (1 − refund) when plan i has a 1st-period price; every renewal at the plan price
Net LTV    = Σ_m Blended[m] × netF,   netF = 1/(1+VAT) × (1 − fee);   in w2w, schedule_i × 0.89 when plan i's retention is a benchmark

Why a sum over billing events and not a retention integral. A subscription pays discretely; retention between billings brings no money. The sum over renewals is the exact analogue of the integral for this business, with fewer assumptions. The alternatives (ARPDAU × lifetime, cumARPU fit, WACC discounting) are described on the LTV methodology tab.

Why M13. An honest cutoff: 12 months of payments plus the first annual renewal. Beyond that is extrapolation, and discounting starts to matter only at $100k+/month with a 12+ month payback.

Intro price (decision 4 Sep 2026, after the run on a real w2w funnel). Each plan has an optional "1st-period price": the first payment (net of refunds) is charged at it, every renewal at the plan price; for yearly the first year is at the intro price, the renewal at the full price, and the high-price ramp is evaluated on the renewal price. Blank = no intro offer. Why: quiz funnels almost always have one (a discounted first week or first year, then the full price); without the field the w2w mode described none of them, and a yearly plan that doubles at renewal had to be emulated with a doubled renewal rate. On a real funnel the field closed the remaining gap to the team's own model to within a couple of percent on monthly and yearly. Downsell plans (failed / cancel offers) are not modeled – captioned.

8.1 Monthly

schedule = [P·(1 − refund), P·S(1), …, P·S(12)],  S – log-log interpolation through the anchors M1, M6, M12

Anchors: M1 50/61/68% [E, our band; RC's category medians of the 1st monthly renewal span 42–61%], M6 14/20/26% [B, RC], M12 6/10/14% [B, RC]. The curve passes exactly through the anchors and agrees with RC's renewal chain 57→71→78% (M2 39.6% vs 40.5%, M3 30.8% vs 31.6%). Checked against a hand-built model of one real app (four retention scenarios): the calculator reproduces the hand-drawn curve within 2%.

AI product: benchmark anchors M6/M12 ×0.7 [E, RC: AI apps churn ~30% faster / "retain 36% worse" over 12 months]; not applied to typed anchors nor in fit mode (self-test).

Why three anchors and not 12 points. RC publishes M6 and M12; everything in between is shape, and log-log (power-law decay) is the standard shape for subscription churn. Storing 12 points = 12 [A] instead of one.

The anchors are editable (decision 4 Sep 2026). In benchmark mode the M1/M6/M12 fields and weekly renewals 1–3 are visible and can be overridden (dimmed if the plan is off); in fit mode they are hidden – there only the first two renewals are asked for. Before, the rows were always hidden "because nobody knows their M6" – but whoever has six-month cohorts does know it, and the promise "override anything you actually know" was not kept for retention. A typed anchor is an effective value: the AI modifier ×0.7 is not applied on top (self-test).

8.2 Yearly

schedule[0] = P·(1 − refund),  schedule[12] = P·renewal × highPriceF(P)
highPriceF(P) = 1 − 0.2 × clamp((P − 50) / 20, 0, 1)      – ×1.0 up to $50, linear down to ×0.8 at $70, flat after

Renewal [B, RC]: 22/30/40%. High-price penalty ×0.8 [B, RC: 1st-renewal churn 37% vs 24% for expensive vs cheap annual plans].

Why a ramp and not a threshold (decision 4 Sep 2026). RC gives two groups but not the boundary between them; we know it roughly as "$60 ± $10". Under a uniform uncertainty of the boundary on [$50, $70] the expected penalty is exactly a linear ramp, not a step. The step at $60.01 also sat two cents from the default price $59.99 and caught "Prices +20%" in sensitivity. Consequence: $59.99 now sits at ×0.90, the default net LTV is $63.29 instead of $64.08 (−1.2%); the self-test snapshot was updated. Since 05.09 (evening) the default yearly price is $49.99 – the last price at ×1.0 – so the untouched default no longer opens with the ramp warning; the default net LTV is $58.49, and the $59.99 case ($63.29) lives on as the cross-tool self-test snapshot in the LTV calculator. RC's 30% median is read as the renewal of the cheap plan (conservative: the median already contains the expensive ones).

8.3 Weekly (decision 4 Sep 2026)

renewal chain w1 (35/46/58%) → w2 (67/71/75%) → w3 (74/80/85%) [B, RC]
→ two-phase geometric tail through two RC anchors: S(26) ≈ M6 = 10% and S(52) = Y1 = 1.5% [B]
anchors scale: M6_eff = 10% × (s3 / s3_median), Y1_eff = 1.5% × (s3 / s3_median), s3 = w1·w2·w3
53 payments (weeks 0–52 = M0…M12, as for monthly), bucketed by month at 52/12 weeks

Why a two-phase tail. The Retention curves tab always drew weekly through the RC anchor M6 = 10% (two-phase), while the calculator counted money on a one-phase tail from the 3rd renewal straight to 1.5% at week 52 – M6 came out at 6.8%, weekly LTV 13% below the curve the tool itself displayed. Now both use one function weeklySurv – agreement by construction (self-test).

Why the anchors scale with the early renewals. The tail gives 2/3 of weekly LTV. Pinned to a fixed 10%/1.5% it "rescued" any cohort: with a 10% first renewal the model still held 1.5% at week 52 and 1.57 → 6+ payments. Scaling the anchor level by s3/s3_median means: the decay shape after the 3rd renewal is RC's median (p1 = 0.959/week to week 26, p2 = 0.930 after), and the level is set by your first three renewals. Side effect – the scenarios reproduce RC's Y1 corridor of 1–2% on their own: P25 → 1.0%, P75 → 2.1%.

Rejected. Scenario P25/P75 for the M6/Y1 anchors themselves – RC publishes only the Y1 range "1–2%", no quartiles for M6; scaling gives the same range without new [A]. Keeping the one-phase tail and bending the tab to it – the tab is closer to the data (it has the M6 anchor).

The W26 anchor is an editable field (decision 4 Sep 2026, after the run on a real w2w funnel). For one real weekly plan with early renewals well above RC's median, churn after the 3rd renewal did not slow down the way RC's panel does: observed week-26 survival came in below RC's 10% while the scaled anchor predicted about twice that, so the calculator overstated the team's own weekly LTV by more than half, and fit mode (a power law through two points) by a multiple. "Weekly survival at week 26 (≈ M6)" is now a field in the retention block, symmetric to M6/M12 for monthly: default RC 10% × s3/s3_ref [E], Y1 follows at the RC ratio (1.5 ÷ 10), a typed value is used as is; the caption and the explain line say "the least certain number in weekly LTV – two thirds of it sit in the tail". With the typed W26 the gap on the same funnel shrinks to a few percent. Rejected: capping the anchor scaling from above (e.g. ×1.5) – a new [A] from one app; changing RC's shape for everyone – one app is no basis. Weekly in fit mode – §8.4.

Result on the default ($5.99 weekly, median): 6.92 payments, gross $41.4 (was 6.13 / $36.5, +13%); P25 4.98, P75 9.29 payments.

8.4 Fit mode (early stage)

monthly:  S(m) = S₁ · m^(−b),  b = −log₂(r₂);  S(1) = r₁, S(2) = r₁·r₂
weekly:   S(w) = r₁ · r₂^(w−1)   – a geometric tail, churn stays at the 2nd renewal's level (decision 4 Sep 2026)

The user types only the 1st and 2nd renewal – what a dashboard shows after two months. The monthly tail is extrapolated with a power curve; the implied M6/M12 are shown and checked against RC's corridors (above them – the warning "2-point extrapolation is optimistic"). On RC medians the fit gives $66.9 against $63.3 for the benchmark curve (+6%) – the bias is documented and printed. The AI factor is not applied in this mode: your own data already contains the product.

Why weekly is geometric, not a power law. A power law through two weekly points with high early renewals gives a tail of 20+ payments – a multiple of what a real cohort delivered; a geometric tail at the 2nd renewal's churn undershoots the same cohort by roughly a third – conservative and explainable in one sentence: "churn stays where you saw it at the 2nd renewal; the tail improvement present in RC's panel is not credited". The implied W26/Y1 are printed with the RC corridor (5–15% / 1–2%) and a hint to switch to the benchmark curve and type your W26 once you have it. Rejected: scaling RC's shape from r₂ – still far above the same cohort by week 18.


9. Net: what is deducted and in which order

proceeds = price ÷ (1 + VAT) × (1 − fee)

Why plan prices are shared across platforms. An iOS premium on prices is not modeled; in the explain text for Android there is a warning that LTV at US prices is overstated (the ARPU factor ×0.8 [A] is applied on the Funnel tab only – see §12).

Why the geo price index is a warning and not a multiplier. The willingness-to-pay index [B, Adapty: WE ×1.3, TR ×0.29, IN-SEA ×0.6, Gulf ×1.35] is about which prices to set, not about how much people pay at a given price. The user must type local prices; the model hints which.


10. Verdict and targets

Target CPA = Net LTV / target ROAS                      (default ROAS 1.3)
Target CPT = Target CPA × trial→paid / trial share
Target CPI = Target CPA × install→sub
Closes ⇔ Net LTV ≥ target ROAS × modeled CPA(sub)

A two-sided check: targets "from the top" out of LTV against modeled figures "from the bottom" out of CPM. If they do not meet – "CPM must fall by X%": CPA is linear in CPM, so X = 1 − Net LTV / (ROAS × CPA).


11. Sensitivity – "where the headroom is" (decision 4 Sep 2026)

for each benchmark stage k:  target_k = P75 benchmark (for CPM – P25) × the same factors (season, AEO, platform)
                             mult_k  = target_k / current effective value_k
                             bar_k   = ROAS(computeModel({k: mult_k})) / ROAS − 1
retention lever: every retention/renewal field to P75 at once (flag retP75)

Why not ±20%. In a multiplicative chain any stage at +20% gives exactly +20% ROAS; CPM −20% showed "+25%" purely from 1/0.8, and prices +20% crossed the $60 threshold and showed +17%. The chart ranked levers by arithmetic artifacts, not by data. The distance to P75 is the only thing that differs between stages, and it is also the answer to "what to fix first".

What it shows on the default H&F × NA (median): paywall→trial +53%, install→paywall +52%, store CVR +43%, trial→paid +36%, CPM +33%, CTR +25%, retention +13%, organic +12%, click→store +6%. So "the biggest lever in subscription UA is not CPM but reaching the paywall and its conversion" – that is Superwall/RC data, not our opinion.

Rejected. Keeping ±20% with a caption "all equal" – useless. WACC/cash elasticities – not for this tool.


12. The Funnel diagnostics tab – iOS vs Android (decision 4 Sep 2026)

What. Two columns per 100,000 impressions, each its own chain, with a "money check" at the bottom: what one subscriber cost vs what one returns, and ROAS against the target.

column = CPM_base × platform CPM → CTR → click→store → storeCVR(ITS OWN store) × paid-factor → (1 + organic)
       → install→paywall → paywall→trial × platform paywall factor → trial→paid ÷ trial share
column net LTV = LTV_headline ÷ arpuF(selected platform) × arpuF(column) × [this funnel's fee]

Why the ARPU factor is not applied in the calculator itself. There the prices are "as typed": if the user typed Android prices, multiplying by 0.8 counts twice. The tab exists precisely to compare platforms at equal prices, and there the factor belongs. The calculator's explain line warns under platform Android that LTV at US/iOS prices is overstated.

Rejected. Dropping the ARPU factor entirely (equal LTV in both columns): then Android wins on ROAS purely on cheap CPM and high Play CVR – contradicting practice (66–75% of apps earn >80% on iOS). Applying the factor in the calculator – double counting with platform prices.

Self-test: the iOS column on the tab = the calculator at platform iOS on cost per subscriber and net LTV.


13. Cross-checks


14. Minor decisions (4 Sep 2026)


15. Deliberately not modeled (v1)

Frequency / creative fatigue (the CPM Health Checklist's territory) · w2a (v2: quiz front + store back, one new field quiz end → store click) · platform-specific prices · downsell plans (failed-payment / cancel offers – on a real w2w funnel a visible share of customers, at a much lower LTV) · the retention difference between direct and trial cohorts (a warning for Productivity/Lifestyle only) · the LTV bonus of annual AI plans · discounting · the conversion difference between organic and paid · client data (public benchmarks only).


16. Source check (4 Sep 2026) – what changed after an independent verification

An independent check went through 42 claims made by the tool against the live pages of their sources. The accepted corrections are captions and tags only: App Store CVR → SplitMetrics (not AppTweak); CTR a2a → [E]; web CPM → Triple Whale $15.06, no geo split; the email stage → Interact's consistent pairs 62–89%; checkout completion → [E] (Stripe publishes +22.3% from Apple Pay, not 82/58); 1st monthly renewal → RC 42–61% by category; r2m/w2/refund/M6/M12/weekly anchors/price ramp → "RC report chart (PDF), not a public page"; seasonality → [E, read off the Bïrch chart]; pricing index → [E]; ARPU Android → [A]; the Android paywall factor: the cited "2.9% vs 2.6%" are the H&F and Business categories, while RC's real store split is download→paid D35 iOS 2.6% vs Android 0.9% with trial→paid at parity – the numbers were recomputed (§4: iOS ×1.30 / Android ×0.45). Tags of the a2a calculator after the corrections: 9 [B] / 11 [E] / 3 [A] (after adding the W26 anchor [E] – 9 / 12 / 3 of 24 fields).

What the check does not close: the chapters of RC's State of Subscription Apps 2026 report (M6/M12, weekly anchors, refund, the annual price ramp) are a PDF, not public pages; those [B] are supported by the report's charts, not by a link.


17. Decision log

Date Decision Where
4 Sep 2026 Paywall→trial derived from RC install→trial × geo ÷ install→paywall; self-test over all 36 × 3 combinations §4
4 Sep 2026 Cost fields (CPM, the AEO premium) follow the scenario mirrored: Pessimistic = P75 cost; self-test on scenario monotonicity §1
4 Sep 2026 No-trial: direct purchases = trial-start rate × 0.4 [E] (Adapty's 0.6 is a ceiling), directf field, trial→paid break-even in the explain; self-test that the verdict agrees with the rule §5
4 Sep 2026 Funnel tab: store CVR per store in each column, column LTV derived from the headline with the derivation printed, fee from the selector; self-test "iOS column = calculator at iOS" §12
4 Sep 2026 w2w: cost per quiz start = CPC ÷ (click→LP × LP→quiz) without dividing by completion; budget line fixed; self-test §7
4 Sep 2026 Weekly: two-phase tail through RC anchors M6/Y1, one function shared with the Retention tab, anchors scaled by the first three renewals; 53 payments M0…M12; self-tests on anchors and tab agreement §8.3
4 Sep 2026 Sensitivity: levers = distance to P75 (CPM – to P25) with "from → to" printed, retention lever, prices as a line; high-price penalty – ramp $50→$70 instead of a $60 threshold; default snapshot $63.29 / $194.1 §11, §8.2
4 Sep 2026 Texts synchronised with the code: the assumptions list on the Funnel tab (every constant as in the code), the store-CVR explain, the internal logic notes and defaults notes rewritten
4 Sep 2026 Tags from the vertical; retention anchors editable (AI not applied to typed ones); mix hint; no-trial + AEO-trial warning; Gulf VAT 10%; fee per funnel; CPI cross-check on paid CPI; self-tests 26/26 §8.1, §14
4 Sep 2026 Second audit against primary sources: typed yearly renewal without the ramp (self-test); the retention lever keeps the AI factor; 3-day trial ×0.68; Interact stages for w2w (LP→start [A], finish→email 60/65/75 [B]); organic → [E]; AEO attribution; Superwall "average"; H&F CPI cross-check on RocketShip [B]; Meta location fees TR 5% / WE 2–5% §3, §4, §7, §13
4 Sep 2026 AEO on trial start is the default; the pair ×4/×4 [E], parity with MAI by construction (self-test), the pair does not move with the scenario; the cross-check compares the organic equivalent §6
4 Sep 2026 The P25/P75 scenario step fixed as a decision: why not P35/P65, how to read the spread, what the user does with it §1
4 Sep 2026 Benchmark base for install→trial – a selector, default hard-paywall apps (the RC band one quartile up; RC's 10.7% vs 2.1% is [B], the shift [E]); AEO/organic as the basis of the benchmarks (×1.0), MAI ×0.4/×0.4 [E] with parity by construction; cross-check on both bases; default snapshot $63.29 / $83.70 (ROAS 0.76); 29/29 self-tests §2, §4, §6
4 Sep 2026 Independent check of 42 claims against sources: captions and tags corrected (SplitMetrics instead of AppTweak, CTR [E], TW $15.06, Interact pairs, Stripe +22.3%, RC 42–61%, "report PDF" for the retention chapters, seasonality [E], pricing index [E], ARPU [A]); "Trust check" → "Consistency checks" §16
4 Sep 2026 Numbers after the check: paywall factor iOS ×1.30 / Android ×0.45 / Blended ×1.0 (RC 2.6% vs 0.9%, mix 0.65 from the global median 2.0%); ARPU Android ×0.8 / Blended ×0.9 [A]; web CPM NA median $15.06; seasonality Jan–Feb ×0.80, Dec ×1.40; VAT IN/SEA 12%; cross-check against the platform-adjusted composite; default snapshot $63.29 / $79.51 (ROAS 0.80); 30/30 self-tests §4, §2, §9, §12
4 Sep 2026 Fresh-eyes pass: tool texts without internal audit codes or client names; the assumptions list on the Funnel tab rewritten after the source check; the Android first-open tag [E] aligned between the tab and the list; this document checked against the code (every constant, default figures $63.29 / $79.51 / 0.80, scenarios $802 / $182 / $79.51 / $9.42) all
4 Sep 2026 Run on a real w2w funnel (several months of data): the ROAS definition, refund and monthly retention reproduced within 2%; the web-cohort ×0.89 double count on typed/fitted renewals found and fixed (per plan, self-test, 31/31); weekly tail and intro prices logged as open questions §9, §8.3
4 Sep 2026 After the run: a "1st-period price" column on the plans (intro offers; yearly renews at the full price); a "Weekly survival at week 26" field defaulting to RC × s3/s3_ref; the weekly fit is a geometric tail instead of a power law; downsell plans added to "not modeled"; 34/34 self-tests, defaults unchanged §8, §8.3, §8.4, §15
4 Sep 2026 Fresh-eyes pass #2 (correctness · logic · consistency · usability · simplicity): the paywall→trial caption shows both bases; Funnel-tab tags aligned with the fields (CTR [E], SplitMetrics/AppTweak per store, LP→quiz [A], checkout completion [E], Superwall "average"); Retention-tab text on fit mode; Canada VAT aligned with the tab; the W26 anchor tagged [E] (9/12/3 of 24); explain in paragraphs; the default case computed on load; the "CPA target event" selector removed, CPT in the explain chain; the LTV block header names its content; click→LP and email captions (no email step → 100%); warning when W26 ≥ s3; the plan table no longer overflows on mobile; an independent Python replica matches to the cent; 34/34 all
4 Sep 2026 Live link check before publishing: RC (store split, renewals, the SOSA page with 10.7% vs 2.1% and 37.7%, Play billing), SplitMetrics/AppScreenshotStudio, Triple Whale $15.06, Superwall 56%/85%, RocketShip $7.80/$4.90 and CPM $5.40–17.50, TUNE 2017, Lebesgue, Adapty paywall (all six figures), Interact, Mobile Dev Memo, ADCostly, Meta location fees, Stripe vs Paddle – confirmed; AppTweak's page has been updated and no longer shows the H1 2024 category CVRs – the Play figures now link to the citing pages, Adjust (H&F 23.2%) and Adapty (Edu 30.4%), added to the footer; H&F mix: only "annual 60.6%" is [B], the rest [E]; RocketShip's blended CPM $10.20 added to the CPM caption as a second reference §3, §2, §14
4 Sep 2026 Published: the tool moved to mariascales.com/tools/unit-economics-estimator/ (a Tools section with the /tools/ hub, a Tools item in the nav on every page, the old case URL redirects with query/hash preserved; the Stealth case links to the tool). The live file is byte-identical to the reviewed one (sha256), self-test 34/34 on the live site. Regression set for the manual run: 30 states with expected numbers and share links, every link re-opened in a headless browser. Cosmetic: the Aspirational preset printed peak cash "$-0.00" (payback M0) → "$0.00"; no model number touched.
5 Sep 2026 UI rework after the first day live (14 PRs): one Calculator tab with an App→App / Web→Web switch, Funnel diagnostics follow the switch (the other funnel behind "Compare"), Retention curves get a dashed "Your setup" curve, LTV methodology / VAT / Design decisions regrouped under a Reference tab; per-field one-line source stubs with the full note behind "why?" (long notes as bullets), a "show all sources" toggle; error state – a zero in a conversion stage dims the stale results, names the field and marks the input; verdict first, KPI tiles 4×2, how-to as four steps, method notes collapsed with links into this document; VAT table rebuilt per country and checked against Apple / Google Play tax notices (17 rates confirmed, Argentina and Pakistan corrected – the stores do not deduct VAT there); phone nav and tab bar fit at 375px; "grew out of the case" wording; this page published; the short link /unit-economics-calc/ with link-preview tags. Model untouched: 30-state regression identical, 34/34. §14
5 Sep 2026 Fresh-eyes review of the reworked tool: (1) Funnel-tab takeaway now follows the numbers – when the column with the cheaper install / quiz start also returns more (w2w default: Android), it says so instead of "a cheaper subscriber is not the same as a better one"; (2) plan shares that do not sum to 100% – the warning now states what the calculation did (normalized, e.g. 30 / 52 → 37 / 63%) instead of "must be 100%" next to "Calculated"; (3) LatAm VAT default 17% → 13% [A] – simple average of the six markets in the corrected VAT table (revenue-weighted ~12%); (4) fit mode with untouched placeholders is labeled as placeholders and no longer raises the "above the RC band" flag before anything is typed; (5) the four tabs stay on one line on phones. Only (3) moves a number, and only for the LatAm geo default. §9, §12, §14
5 Sep 2026 SEO and copy pass (external review): the tool page gets an h1, og:type website (the short link already said so), a 150-character description, og:site_name / og:locale / og:image:alt and JSON-LD (SoftwareApplication + BreadcrumbList; this page: TechArticle + BreadcrumbList); the two redirect stubs drop noindex (canonical + redirect carry the signal) and the short link drops the analytics tag; sitemap lastmod bumped. Copy: the hook "Does this growth math ever close?" opens the page and the scope follows; percentage fields show a % unit and CPM a $, the paid-traffic and organic-uplift labels name the unit; one name per metric – ROAS (net LTV ÷ CPA) and CPA (cost per subscriber) everywhere; a jargon line (AEO, MAI, VO, SBP, M13, P25/P75, CPT, CPA); American spelling; dates written as 4 Sep 2026. §14
5 Sep 2026 Reference › Data sources: a fourth sub-tab with the checklist of where each of the calculator's 35 inputs comes from in a company's own systems – Ads Manager, MMP, App Store Connect / Play Console, RevenueCat / Adapty, product analytics, Stripe, the warehouse – with the definition the model uses, the report to read, the cut and history that make the number trustworthy, and the trap per field (App Store Connect's "Conversion Rate" is impression-based while the model wants page view → download; a typed CPM is used as is – no seasonality or optimization premium on top); step 3 of the how-to links to it. Model untouched, 34/34. §0, §14
5 Sep 2026 LTV Calculator released as a separate page (/tools/ltv-calculator/, short link /ltv-calc/): the estimator's LTV engine without the acquisition funnel – Setup reduced to the selectors that move LTV (vertical, geo, scenario, billing in-app / web, fee, AI), the same plans table and retention fields, results as net and gross LTV M13, the deduction chain, a per-plan table (one subscriber on each plan, its contribution to the blend), a cumulative net-revenue curve M0–M12+ and a "your CPA" block (ROAS, payback month, target and break-even CPA, peak cash) that re-renders live. Not a mode of the estimator but a second page, so the engine is mirrored: the page is assembled from the estimator by build_ltv_calculator.py (engine blocks copied, never retyped), check_ltv_mirror.py fails the commit when any of the 13 engine blocks differ, and both tools' self-tests assert the same default net LTV ($63.29). 22 self-tests; Reference carries the LTV part of the Data sources checklist plus a "Your CPA" row. Deferred to a mirrored follow-up: a mode that takes a cohort's own retention curve. §8, §9, §14
5 Sep 2026 Default yearly price $59.99 → $49.99 in both tools. The untouched default opened with a warning – "Yearly renewal at M13: benchmark 30% × price ramp ×0.90 at $59.99" – because $59.99 sits inside the RC high-price ramp ($50 → $70); a first-time visitor saw a yellow flag before touching anything. $49.99 is the last price at ramp ×1.0, so the default case is clean and the ramp still shows the moment someone types a $59.99 plan. Consequence: default net LTV $63.29 → $58.49 (yearly gross $74.09 → $63.24 = 49.99 × (1 − 3.5%) + 49.99 × 30%); modeled CPA, CPI and every acquisition number unchanged; ROAS on the default 0.80 → 0.74. Regression set recomputed (30 estimator states + 10 LTV-calculator states, every share link re-opened headless); the LTV scenario L3 moved from CPA 45 to CPA 40 because 58.49 ÷ 45 is exactly 1.30× and read as "does not close, headroom 0%". Self-tests: the estimator snapshot follows the new default ($58.49); the LTV calculator keeps the $59.99 case ($63.29) as the cross-tool fixture. §8, §14