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.
Format
Impressions
Revenue
Banner
48%
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.
Format
eCPM
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 days
July
October
Rewarded ads asked for
1,461
560
Rewarded shown
18%
83%
Rewarded earned
€6.68
€12.14
Interstitials shown
19%
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 key
Live
What it decides
ads_<format>_enabled × 4
true
an off switch for each format
ad_ri_frequency
500
hands between rewarded interstitials
ad_interstitial_frequency
20
hands between interstitials
ad_app_open_daily_cap
1
app open ads per day
ad_app_open_min_hands_played
20
hands 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, CEST
Remote Config
21:56
rewarded interstitial: every 10 hands → every 20
22:02
rewarded interstitial: off
22:02
…and every interstitial stops, on each phone as it fetches
22:40
workaround: on again, every 500 hands
next day
the 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 Stories
Price
Trial
Weekly — listed first
€2.99
3 days
Yearly
€34.99
7 days
Monthly
€4.99
7 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 Day
Bedtime Stories
Active subscriptions
7
0
MRR
€22
€0
Who sees the paywall
everyone who finishes onboarding
15 of 25 readers
Tap to buy
13% of views
0 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 for
10 minutes
A whole day
Rewarded ads per user
1.83
0.74
Ad money per user
8.6¢
3.2¢
Back the next day
34%
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 Notes
The screen said
The code would
Rewarded ad
Watch it, get a life
End the run anyway
Paywall
Free trial
Charge 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.
When
Job
Speaks when
07:00
Revenue, users, subscriptions, reviews
every day — one message
08:00
Crashlytics, every app
only past a threshold
every 15 min
Sentry, every backend
only if new, regressed or escalating
Monday
Dependency updates
a PR per repo, tests green
any time
A job that dies
its 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 days
Before 15 Aug
After
Revenue
€47
€10
Impressions
4,694
1,036
Shown
40%
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.
Who
What
Where
Kindle Gratis
carousel: today's 3 free books, from the app's data
TikTok · EN + DE
3 Things a Day
promo reel, one caption per network
TikTok · X · LinkedIn
One app a day
daily standup, from git
X · LinkedIn
Me
what I earned last month: €215 in September
X · 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 onboarding
5 of 206 reached the story
Startup time
a slow first launch gets no second
Paywall copy
13 views, 0 taps
Analytics
2 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.