Show Me the Money

Ivan Morgillo

DevFest Venezia · 24 Oct 2026

I€
€

Why I looked

I€

I · Cold open

A paywall that works. €0.

Bedtime Stories · August
Installed49
Asked for a story32
Read it to the end25
Reached the paywall15
Started a trial0

Every event fired. Every screen rendered. Billing works. €0.00.

I · Who is talking

15 years of mobile.
Last year everything changed.

I · Who is talking

1 person. 14 apps. 0 team.

14apps on Android
13of them on iOS too
1.5Minstalls, one app

Every install organic, out of Play Store search. No budget, no marketing department, no cofounder. Releases scripted, metadata in the repo, social by a bot.

I · The claim

Money is a quality feature.

  • Downloads flatter you
  • Ratings flatter you
  • Revenue does not

To be paid you must measure. To measure is to find out.

II€
€€

What the money said

II€

II · The first look

57% of the money. 11% of the ads.

FormatImpressionsRevenue
Banner48%16%
Rewarded + rewarded int.11%57%

23,000 banner impressions → €27.
5,400 rewarded → €95.
Rewarded is the format I refused for a year.

II · The first look

6 formats. 44× the price.

FormateCPM
Native, badly placed€0.54
Banner€1.19
App open€7.31
Interstitial€8.24
Rewarded interstitial€13.75
Rewarded€23.64

Whole portfolio, September: same users, same month. A factor of 44.

II · The first look

Half the ads. The same money.

−58%ads per hour of play
+3%money per hour of play

Blackjack Android, 30 days either side of 18 August. The banner held 68% of impressions at €1.25 eCPM. People also played 46% longer; I cannot prove the banner is why.

II · The bugs were mine

Loading an ad is not showing an ad.

Kindle Gratis · 7 daysJulyOctober
Rewarded ads asked for1,461560
Rewarded shown18%83%
Rewarded earned€6.68€12.14
Interstitials shown19%72%

Same price per rewarded ad: €25.51 then, €26.16 now. Weeks of 15–21 July and 29 Sep – 5 Oct.

II · The bugs were mine

When the ad failed to load, the paid books were free.

if (rewardedAd.isReady) {
    showAd { unlockBook() }
} else {
    unlockBook()          // no ad? have it for free
}

Every failed load — bad network, no fill, expired — opened the entire premium catalogue. The leak only opens when monetization is already failing.

III€
€€€

The controls

III€

III · Switches, not releases

Every ad has a switch. None of them needs a release.

Remote Config keyLiveWhat it decides
ads_<format>_enabled × 4truean off switch for each format
ad_ri_frequency500hands between rewarded interstitials
ad_interstitial_frequency20hands between interstitials
ad_app_open_daily_cap1app open ads per day
ad_app_open_min_hands_played20hands before the first app open ad

Blackjack Trainer, live values. Every value is clamped in the app; the switches mirror defaults in the code, so a Remote Config outage leaves the ads on. The rewarded interstitial made 81% of the app's ad revenue in September.

III · Switches, not releases

I switched 1 ad off. Every interstitial stopped.

4 October, CESTRemote Config
21:56rewarded interstitial: every 10 hands → every 20
22:02rewarded interstitial: off
22:02…and every interstitial stops, on each phone as it fetches
22:40workaround: on again, every 500 hands
next daythe real fix, merged in the code

A spacing rule read a disabled format as one that was just shown. The off position of a switch is a code path. Test it.

IV€
€€€€

The paywall

IV€

IV · Subscriptions

€2.99 a week. 0 sold so far.

Bedtime StoriesPriceTrial
Weekly — listed first€2.993 days
Yearly€34.997 days
Monthly€4.997 days

Weekly available since 26 September, listed first in the app. One Italian price, equalised across 175 App Store territories — for now.

IV · Subscriptions

2 apps. 2 paywalls. 1 sells.

3 Things a DayBedtime Stories
Active subscriptions70
MRR€22€0
Who sees the paywalleveryone who finishes onboarding15 of 25 readers
Tap to buy13% of views0 trials

IV · Experiments

We are in the middle of it.

  • Bedtime: does weekly-first sell? First numbers by November
  • Bedtime: the paywall at the end of the first story
  • Prices by country, not one Italian price everywhere
  • Smart Pantry Plus, no ads: 2 yearly in its first week

One answer so far: 4 Plus sold, €74. The app's ads made €5 in all of September.

IV · Experiments

10 minutes beat a whole day.

Kindle Gratis · 1 ad opens VIP for10 minutesA whole day
Rewarded ads per user1.830.74
Ad money per user8.6¢3.2¢
Back the next day34%32%

A/B test, 2–8 October. Same retention, 63% less money. Stopped.

V€
€€€€€

How one person ships

V€

V · Who checks my work

No QA team. A review panel that never gets tired.

  • A plan — reviewed by other models before any code
  • My approval
  • A pull request — reviewed by models that did not write it
  • Fix every blocker, review again
  • I merge. Nobody else.
ship-feature

1,750 pull requests, 50+ repositories, since June.

V · Who checks my work

1 review.
2 broken promises.

Two NotesThe screen saidThe code would
Rewarded adWatch it, get a lifeEnd the run anyway
PaywallFree trialCharge for a year

Both found by Codex in one review round, before launch.

V · Who checks my work

The build refuses to ship.

  • Built from the tip of the release branch
  • Unit tests green
  • Maestro on a real phone, through the path that pays
  • Release build: no “Test Ad” on screen, ever

Red gate, no upload. My fake ad was once more forgiving than the real one — the test passed while the bug was live.

V · The machine that watches

1 text file. 30% of the revenue.

€5.00eCPM, before
€3.50eCPM, after
0warnings

app-ads.txt broken in a site rebuild. Traffic flat, app unchanged. Programmatic buyers verify it, then quietly stop bidding. I saw it only because I happened to look.

V · The machine that watches

I stopped opening dashboards. They come to me.

WhenJobSpeaks when
07:00Revenue, users, subscriptions, reviewsevery day — one message
08:00Crashlytics, every apponly past a threshold
every 15 minSentry, every backendonly if new, regressed or escalating
MondayDependency updatesa PR per repo, tests green
any timeA job that diesits name and its log

app-tools: one CLI over AdMob, GA4, Search Console, both stores and RevenueCat — and an MCP server.

V · The machine that watches

The month my best format stopped firing.

KG · app open, 30 daysBefore 15 AugAfter
Revenue€47€10
Impressions4,6941,036
Shown40%11%
eCPM€9.98€9.68

The price never moved. The ad stopped being shown. −79%, about €37 a month, for six weeks.

V · The machine that watches

7 in the morning. 1 message.

Show rate — filled → shown

Smart Pantry (A)    app open        503 →   8     2%
Ebooks for Kindle   app open       5726 → 606    11%
StreakUp (iOS)      interstitial    395 → 105    27% ⚠

⚠ = interstitial under 30% with 300+ requests:
    the app loads them and never shows them

From the daily report of 21 September, translated from Italian. The warning covers interstitials only — which is why the Kindle line never got one. Same week: a backend job that failed ~680 times and reported success became the Sentry job.

VI€
€€€€€€

Growth

VI€

VI · The doors

An ad unit with no users pays exactly €0.

€24eCPM
× 0users
= €0revenue

Everything before this multiplies one number: the people inside the app. Two doors I can work on: the store listing, and what the apps post. I have never paid for an install.

VI · The doors

Conversion 26% → 36%, same app.

  • The icon
  • The first two screenshots
  • The first line of the description — the only line anybody reads

26.3% → 35.7% install conversion. A third more users, every day, forever, for one afternoon. Not a feature — a better sentence.

VI · The content machine

Something goes out every day. A machine makes it.

WhoWhatWhere
Kindle Gratiscarousel: today's 3 free books, from the app's dataTikTok · EN + DE
3 Things a Daypromo reel, one caption per networkTikTok · X · LinkedIn
One app a daydaily standup, from gitX · LinkedIn
Mewhat I earned last month: €215 in SeptemberX · LinkedIn

Rendered with HyperFrames, published with Buffer. Reels: github.com/hamen/app-promo-reel (MIT).

VI · The content machine

The hook moved to frame 0.

~1 saverage watch time
29 → 240views, video A
111 → 244views, video B

Same two videos, old hook vs new. A tiny sample — posted on different days. Still testing.

VII€
€€€€€€€

Back to the claim

VII€

VII · What it made me fix

What the money made me fix

What money made me fix
Login wall + 4-screen onboarding5 of 206 reached the story
Startup timea slow first launch gets no second
Paywall copy13 views, 0 taps
Analytics2 years of guessing

Not one of these is monetization work. Every one came out of looking at money.

VII · What it made me fix

You cannot be paid by a user who wants nothing.

57%of the money
11%of the impressions

Rewarded + rewarded interstitial. A rewarded ad is a trade — nobody can be tricked into it. My best format is a measurement of whether I built something worth wanting.

VII · What it made me fix

Money finds the bug. It will not fix it.

900+customers, lifetime
€0revenue, lifetime
3paywall rewrites

Revenue is the best defect detector I have ever had, and a terrible engineer. It finds the bug, then stands there looking at you.

VII · Close

The checklist

  • Check app-ads.txt today — the cheapest alarm you will ever install
  • Make the numbers come to you — one message, every morning
  • Sort revenue by format, not by impression count
  • Put every ad behind a switch — and test the off position
  • Let a model that did not write the code review it
  • Show the paywall to everyone who could buy
  • Count every step to the paywall, and find where people leave

Bedtime Stories, April: 5 of 206 reached the story.

VII · Close

Ask me the uncomfortable ones.

  • ivanmorgillo.com
  • indiepa.ge/ivanmorgillo — every app, numbers included

Every number here came off my own dashboard, including the ones that embarrassed me.

Grazie.

ivanmorgillo.com · indiepa.ge/ivanmorgillo