Ad monetization is one of the most accessible revenue models for indie app developers. You don’t need a massive user base to start earning, and the barrier to entry is low. But there’s a significant gap between “showing ads in your app” and “maximizing ad revenue without destroying the user experience.” After a year of running ads in my Flutter apps, I’ve learned that the difference often comes down to strategy and continuous optimization.
Understanding the Core Metrics
Before optimizing anything, you need to understand what you’re measuring. These are the metrics that matter most:
eCPM (Effective Cost Per Mille)
eCPM represents how much you earn per 1,000 ad impressions. It’s the single most important metric for comparing ad performance across formats, networks, and placements. A higher eCPM means each impression is worth more.
Typical eCPM ranges for indie apps:
- Banner ads: $0.50 - $2.00
- Interstitial ads: $3.00 - $12.00
- Rewarded video ads: $8.00 - $25.00
- Native ads: $2.00 - $8.00
These numbers vary dramatically based on geography, app category, user demographics, and time of year.
Fill Rate
Fill rate is the percentage of ad requests that actually return an ad. A 90% fill rate means 10% of the time, the ad network has no ad to show. Low fill rates mean lost revenue opportunities. Typical fill rates for AdMob range from 85-99%, depending on your region and app category.
Impressions and Impression Rate
Total impressions measure how many ads were actually viewed. Impression rate is the percentage of active users who see at least one ad. This metric helps you understand if your ad placement is actually reaching users.
Revenue Per Daily Active User (ARPDAU)
This is the ultimate metric — how much revenue each active user generates per day. It combines all the above metrics into a single, actionable number. For most indie apps with ads, ARPDAU ranges from $0.01 to $0.10.
Choosing the Right Ad Formats
Not all ad formats are created equal, and the right choice depends heavily on your app type and user behavior.
Banner Ads
Banners are the simplest format — a rectangular ad that sits at the top or bottom of the screen. They have the lowest eCPM but also the lowest user friction.
// Simple banner ad implementation in Flutter
class BannerAdWidget extends StatefulWidget {
@override
_BannerAdWidgetState createState() => _BannerAdWidgetState();
}
class _BannerAdWidgetState extends State<BannerAdWidget> {
BannerAd? _bannerAd;
bool _isLoaded = false;
@override
void initState() {
super.initState();
_loadAd();
}
void _loadAd() {
_bannerAd = BannerAd(
adUnitId: AdHelper.bannerAdUnitId,
size: AdSize.banner,
request: const AdRequest(),
listener: BannerAdListener(
onAdLoaded: (ad) => setState(() => _isLoaded = true),
onAdFailedToLoad: (ad, error) {
ad.dispose();
},
),
);
_bannerAd!.load();
}
@override
Widget build(BuildContext context) {
if (!_isLoaded) return const SizedBox.shrink();
return SizedBox(
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
);
}
}
Best for: Utility apps, content apps, and any app where users spend extended periods on a single screen.
Interstitial Ads
Full-screen ads that appear at natural transition points. They command higher eCPMs but must be used carefully to avoid annoying users.
Best for: Games (between levels), content apps (between articles), and any app with natural pause points.
Key rule: Never show an interstitial that interrupts the user mid-task. Show them at transition points — between levels, after completing an action, or when navigating between sections.
Rewarded Video Ads
Users voluntarily watch a video ad in exchange for an in-app reward. These have the highest eCPMs because advertisers know the user is engaged and watching the full ad.
Best for: Games (extra lives, power-ups, currency), any app where you can offer a meaningful reward.
In my balloon-popping game, rewarded videos are the top revenue driver. Players can watch a video to get an extra life or unlock a special balloon type. The key insight is that the reward must feel valuable enough that users actively seek out the ad.
Native Ads
Ads that match the look and feel of your app’s content. They blend in seamlessly and typically have moderate eCPMs with higher engagement rates.
Best for: News apps, social feeds, list-based interfaces.
Optimal Ad Placement
Where you place ads matters as much as which format you choose. Poor placement leads to either low visibility (wasted inventory) or user frustration (high churn).
The Golden Rules of Ad Placement
-
Place ads at natural content boundaries. Between levels, at the end of articles, in list feeds between every 5-8 items.
-
Never cover content the user is actively engaging with. This is the fastest way to drive uninstalls.
-
Give users control when possible. Rewarded ads work precisely because the user chooses to engage. This principle applies broadly — users are more tolerant of ads they feel they have control over.
-
Respect the first impression. Don’t show ads immediately when the app launches. Let users engage with your content first. I wait until after the user has completed their first game session before showing any ads.
-
Frequency capping matters. Showing too many interstitials per session drives users away. I cap interstitials at one per 3-4 minutes of active usage. For rewarded videos, I allow more frequent viewing since they’re user-initiated.
A/B Testing Ad Configurations
You should test different configurations to find the optimal balance. Test variables include:
- Ad frequency: How often interstitials appear
- Placement position: Top vs bottom banners, which transition points
- Ad format mix: The ratio of banners to interstitials to rewarded ads
I track these experiments using Firebase A/B Testing alongside AdMob. Run each test for at least two weeks to account for day-of-week variations, and focus on ARPDAU as the primary metric — not just ad revenue, but also retention. A configuration that earns 20% more per impression but drives away 30% of users is a net loss.
Ad Mediation
Ad mediation allows multiple ad networks to compete for your inventory, typically increasing your eCPM by 20-50% compared to using a single network.
How Mediation Works
When your app requests an ad, the mediation layer sends the request to multiple networks simultaneously (or in a waterfall sequence). The network that offers the highest bid wins the impression. This competition drives up the effective price you receive.
Setting Up AdMob Mediation
AdMob offers built-in mediation that’s straightforward to configure:
- In your AdMob dashboard, navigate to Mediation > Create mediation group
- Select your ad format and target platforms
- Add mediation partners (Unity Ads, AppLovin, Meta Audience Network, etc.)
- Configure the waterfall or enable bidding for supported networks
- Set eCPM floor prices if desired
Important: Each mediation partner requires their own SDK integration. This adds to your app’s binary size and initialization time. For indie developers, I recommend starting with 2-3 networks maximum. Adding more networks beyond that shows diminishing returns.
My Mediation Experience
I started with just AdMob and later added mediation with two additional networks. The result was a 35% increase in eCPM over three months. The biggest gains came from the competition itself — knowing that another network might win the impression motivated each network to bid higher.
Seasonal Revenue Patterns
Ad revenue is not constant throughout the year. Understanding seasonal patterns helps you set realistic expectations and plan accordingly.
The Annual Revenue Cycle
- Q4 (October-December): Highest eCPMs. Advertisers spend heavily for holiday shopping season. eCPMs can be 40-80% higher than annual average.
- Q1 (January-March): Significant drop. Advertising budgets reset after the holidays. January is typically the lowest revenue month.
- Q2 (April-June): Gradual recovery. eCPMs climb back toward average.
- Q3 (July-September): Moderate. Back-to-school advertising provides a small boost in August-September.
My monthly revenue from Happy Balloon Pop follows this pattern almost exactly. December revenue was roughly double what I earned in January. Knowing this in advance prevents the panic of seeing a revenue drop in Q1 — it’s expected.
Weekly and Daily Patterns
- Weekends typically show lower eCPMs but higher impressions (more users)
- Evening hours generally have higher eCPMs than daytime
- Holidays can go either way — more users but sometimes fewer active advertisers
COPPA-Compliant Monetization for Kids’ Apps
If your app targets children under 13, COPPA compliance is non-negotiable. This significantly impacts your monetization strategy.
What COPPA Means for Ads
- No behavioral or interest-based targeting
- No personalized ads
- Limited ad formats (no ads that look like game elements)
- Strict data collection limitations
In AdMob, enable child-directed treatment:
final adRequest = AdRequest(
extras: {
'tag_for_child_directed_treatment': '1',
'max_ad_content_rating': 'G',
},
);
Revenue Impact
COPPA-compliant ads typically earn 40-60% less than unrestricted ads because advertisers can’t target effectively. This is the reality for kids’ app developers, and it should factor into your business planning.
For my apps that target younger audiences, I offset this by focusing on rewarded video ads (which tend to maintain higher eCPMs even under COPPA restrictions) and ensuring high user engagement to maximize impression volume.
Realistic Revenue Expectations
Let me be direct about what indie developers can realistically expect from ad revenue:
Small Scale (1,000-5,000 DAU)
- Banner ads only: $1-10/day
- Mixed formats: $5-25/day
- Monthly: $30-750
Medium Scale (5,000-20,000 DAU)
- Banner ads only: $10-40/day
- Mixed formats: $25-100/day
- Monthly: $750-3,000
Larger Scale (20,000-100,000 DAU)
- Mixed formats: $100-500/day
- Monthly: $3,000-15,000
These numbers assume a well-optimized app with good ad placement and mediation. Many indie apps fall below these ranges, especially in the early months.
Ad revenue is a marathon, not a sprint. The most successful indie developers I know focus on building sustainable user growth rather than squeezing maximum revenue from existing users.
My Monetization Journey
When I first launched Happy Balloon Pop, I made several classic mistakes:
- Showing banner ads on every screen from the first launch
- Displaying interstitials too frequently (every 2 minutes)
- Not implementing rewarded video ads at all
The result was poor retention and mediocre revenue. Users downloaded the app, hit a wall of ads, and left.
I then revised my strategy:
- Removed all ads from the first session
- Reduced interstitial frequency to once per 4 minutes of active play
- Added rewarded video for extra lives and power-ups
- Moved banner ads to non-game screens only
The result was counterintuitive — I showed fewer ads but earned more. Retention improved by 45%, which meant more daily active users, which meant more total impressions, which meant more revenue despite the lower per-user impression count.
The lesson: user experience and monetization are not opposing forces. When you respect the user’s time and attention, they stick around longer and engage more willingly with the ads you do show. Optimize for lifetime value, not single-session extraction.
Action Items for Indie Developers
- Start with a single ad network (AdMob) and one format, then add complexity
- Implement rewarded video ads as early as possible — they’re the highest-value format
- Cap interstitial frequency and never interrupt mid-task
- Set up mediation once you have consistent traffic
- Track ARPDAU alongside retention — optimize the combination, not just revenue
- Plan for seasonal fluctuations and don’t panic during Q1 dips
- If targeting children, budget for lower eCPMs and plan accordingly
- Test changes with A/B experiments, not gut feelings
Ad monetization rewards patience and systematic optimization. The developers who succeed are those who treat it as an ongoing process rather than a set-and-forget implementation.