If you run a wallpaper app long enough, there comes a point where revenue flattens out almost too neatly. Downloads and active users haven't dropped much, yet ad revenue just stops growing. That plateau is exactly what I've been wrestling with recently.
When I traced the cause, I kept arriving at the same place: mediation. That's the layer that serves multiple ad networks together and hands each impression to whichever network pays the most. I had left this part on auto-optimization for years, and when I finally went back and looked at it by hand, I found more "set-and-forget traps" than I expected. Here are the notes from that process, written up as an operations log.
Question the assumption behind leaving it all on auto
AdMob has a feature called "optimized ad networks." For networks that support real-time bidding (open bidding), the higher-paying one is generally chosen for you automatically. I took that explanation at face value and barely opened the settings screen for a long time.
But when I actually broke the "Mediation" report down by country and by network, a few things started to bother me.
- Some "waterfall" networks that don't support real-time bidding had been left sitting on stale, hard-coded eCPM values
- In certain regions, a network that should have been able to buy at a higher price was sinking down the bid order because of a low eCPM setting
- A couple of networks were technically serving but had an extremely low fill rate (the share of ad requests that actually return an ad)
Auto-optimization only operates within the real-time bidding lane. The fixed values on networks left in the waterfall stay outdated for years unless you revisit them yourself. Leaving that untouched was part of why things had stalled.
First, pinpoint where you're leaking money, in numbers
Before touching anything, I decided to understand the current state with data rather than gut feeling. From the AdMob dashboard, I looked at four things:
- eCPM per network (effective revenue per thousand impressions)
- Fill rate
- Impressions
- Breakdown by country and region
The country breakdown was what really mattered. Most of my wallpaper app's downloads come from English-speaking regions and Japan, and eCPM differed by nearly threefold between the two. Numbers that feel like "well, that's about normal" at the overall average suddenly reveal rooms with real upside once you split them by region.
What I kept reminding myself was: don't be fooled by averages. Even when overall eCPM looked flat, the breakdown sometimes showed "high-value region slightly down" and "low-value region slightly up" simply canceling each other out. It looked like a plateau, but really I had just lost visibility into the changes happening underneath.
Adjust the waterfall's fixed eCPM in small steps
Once the problem was visible, I revisited the fixed eCPM values on the networks still in the waterfall. A common mistake here is raising the value sharply all at once. If you set the fixed eCPM too high, that network moves up the bid order, but no buyer materializes at that price, so the ad doesn't actually serve and your fill rate drops.
What I did instead was adjust gradually, in 10–15% increments, using the past 30 days of actual eCPM as a baseline.
- Write out each network's actual eCPM from the recent report
- Leave real-time bidding networks on auto, as a rule
- Move only the waterfall networks' fixed eCPM closer to their actual values
- Run it for a few days and check that fill rate and impressions haven't dropped
- If it's fine, make the next adjustment; if it dropped, step back one notch
It's unglamorous work, but repeating this "nudge a little, watch for a few days" loop reveals the band where you can raise the price without strain, and the line beyond which serving simply stops. Rather than trying to nail it in one big change, small increments settled down faster in the end.
Separate the part you automate from the part you watch by hand
While working through this, I've been using Claude in Chrome to fetch and organize the reports. Reading the by-country, by-network figures off the dashboard and tabulating the differences from last time is a repetitive chore that's a real burden to copy out by hand every week. Automating the data-tidying freed me up to spend time on the part that matters: deciding what to move and how.
I draw a clear line here. The work of collecting and organizing numbers goes to automation; the final call on how to change priorities I make myself. Precisely because these settings tie directly to revenue, the last step should have a human looking at it. How you present ads changes the user's experience, and that, like making art, is a place where I want to keep the feel of my own hands on it.
How it feels after a few weeks
It's not a flashy tactic, so revenue doesn't leap overnight. Still, by moving the neglected waterfall values closer to actuals and tidying priorities region by region, the stalled eCPM has slowly started to respond. More than anything, being able to explain in numbers exactly which region, which network, and how my app's revenue is generated felt like the real reward.
Mediation isn't something you set once and walk away from; the optimal point drifts a little with the seasons and with changes on the networks' side. Next, I plan to retire the networks with chronically low fill rates, simplify the lineup, and watch whether bidding runs more healthily on a leaner setup.
If you're stuck on the same revenue plateau as an indie developer, I'd suggest starting by breaking your mediation report down by country. You may find more upside hiding behind the average than you'd expect. Thank you for reading.