The thing that made the biggest difference in my indie app’s revenue design wasn’t the price, and it wasn’t which ad network I picked.
It was changing the free tier from 2 stories a day to 1 story a day.
This is about Nemuru, my AI bedtime picture book app. Here are the numbers, and the reasoning behind that decision.
The final numbers
- ¥300 monthly / ¥2,000 yearly / 7-day free trial
- Free users get 1 story a day. Watching a rewarded ad unlocks 1 more story that day (up to 2 stories a day)
- Banner ads only on the input screen and the history screen
I deliberately priced it lower than the other 2 apps I released around the same time (the diary app at ¥480, the queue-prediction app at ¥400). I prioritized a simple policy: “keep it as cheap as possible early on, and get lots of people to try it first.”
When I ran the numbers, subscriptions weren’t the main act
When I stacked up the projected monthly revenue, the breakdown looked like this:
Banner ads ¥600 – 800
Rewarded ads ¥2,700 – 4,500
──────────────────────────
Ads total ¥3,300 – 5,300
Subscription ¥300 × 2% conversion = ¥1,200
At this scale, ad revenue clearly beats subscription revenue.
That surprised me. When you think about monetizing an indie app, it’s tempting to design the subscription first and treat ads as “a little extra from free users.” At least, that’s how I thought about it.
Laying the numbers side by side made one thing clear: faced with a realistic 2% conversion rate, the unnatural design is the one that earns nothing at all from the other 98% of users.
Rewarded ads don’t work unless people have a reason to want them
That said, the estimate above assumes people actually watch the rewarded ads. That was the entire design problem.
The monetization agent’s original proposal was “2 free stories a day.” I overrode it to 1 story a day. For one reason:
If you get 2 free stories a day, “I want one more” almost never happens.
Not many families read 3 or 4 bedtime stories in a single night. 2 is enough. And once it’s enough, there’s zero motivation to watch a rewarded ad. You can put the ad slot there, but nobody watches it, so it earns nothing.
Limiting it to 1 story creates the most natural flow:
“The generated story doesn’t fit tonight’s mood” → “Watch an ad and make one more.”
Whether this flow works is worth a difference of just under ¥3,000 a month.
Naturally, there was a concern that “1 story is too tight and people will leave,” and it really did come up for debate. The conclusion was that since watching an ad gets you +1 story immediately, it’s not a dead end. Not a wall, but a paid door and a free door standing side by side.
Revenue hinges on a single piece of UI
This is the one thing the implementation absolutely can’t get wrong.
Right after a free user uses up their 1 story, always show 2 choices.
① "Watch an ad and make one more story"
② "Go Premium"
I made the paywall 2-stage:
| Timing | Type | What it shows |
|---|---|---|
| Right after using up 1 story | Soft | The 2 choices above. The ad is an escape hatch |
| After using up both stories for the day | Hard | Only the path to paying |
What matters is that some people choose ② at the soft stage. Offering ① doesn’t cut into subscriptions. Instead, the 2 choices work as the place that confronts users with the fact that “you can’t make any more today.” If you just stop them silently without offering options, users close the app without choosing anything.
Where I decided never to show ads
I set one principle as something that will absolutely never move:
Never show ads during read-aloud.
This is an app parents use to read to their kids at bedtime. Inserting ads there would probably raise revenue. And the app would never be used again.
Banners only on the input screen and the history screen. Both hidden for premium users. I put this line ahead of the revenue estimate. An ad that breaks the experience trades away the app’s lifespan in exchange for short-term revenue.
Not putting the price in the Product ID paid off 3 days later
It’s unglamorous, but worth writing down.
The monetization agent had named the Product IDs like this:
premium_monthly
premium_yearly
Not a name with the price in it, like premium_380. And right after that, I changed the price from ¥380 to ¥300.
Product IDs can’t be changed once they’re registered in the store. If the price had been in the name, I’d have had 2 options: recreate the products, or keep running with a name that doesn’t match reality. Instead, the change cost nothing.
For the same reason, when I raise prices, I keep existing users on the old price. If the ID is independent of the price, that’s straightforward too.
Play Console trap: the free trial isn’t inside the base plan
Finally, something practical. You will get lost looking for where to set up the free trial.
It’s not on the base plan settings screen. It’s under the “Offers” tab.
Open premium_monthly
→ "Add offer" on the base plan row
→ Choose an offer ID
→ Free trial: 7 days
→ Activate ← it isn't active until you get this far
I burned time searching the base plan screen. I’ve written it into my runbook so I don’t step on it again with other apps.
By the way, this free trial also works as a way for contest judges to try the paid features. Even without issuing separate promo codes, a trial lets judges use Premium. It’s a side benefit, but it satisfied one of the submission requirements.
Summary
- At indie scale, rewarded ads can outperform subscriptions
- But only if you tighten the free tier and create a reason to watch ads
- The key to revenue isn’t ad rates; it’s the 2-choice UI shown the moment the free tier runs out
- Don’t put ads in the core of the experience (for this app, during read-aloud)
- Don’t put prices in Product IDs. Your pricing will change, guaranteed
Once real numbers come in, I’ll publish them, including how far off this estimate turned out to be.
I’ve already published the cost side in full (a ¥22 bill for 3 apps, total cost stayed ¥0 even after upgrading to a paid account). The story of my billing implementation being broken for 11 days is here.