◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/App Dev
◇ App Dev/2026-05-31Intermediate

Retuning AdMob Mediation Priorities: Notes From Trying to Lift My eCPM

A running log of how I manually revisited the network priorities in my AdMob mediation setup to lift eCPM on an indie wallpaper app, what changed compared to leaving it on auto-optimization, and what I noticed along the way.

AdMob73Mediation7App Monetization11Indie Development27

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.

  1. Write out each network's actual eCPM from the recent report
  2. Leave real-time bidding networks on auto, as a rule
  3. Move only the waterfall networks' fixed eCPM closer to their actual values
  4. Run it for a few days and check that fill rate and impressions haven't dropped
  5. 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.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⟐ Business2026-05-21
Putting AdMob Bidding into Production for a Rork App — Five Networks Bidding in Parallel, eCPM Trends, and Daily Operations
I moved the AdMob mediation layer of my Rork-generated apps from waterfall to bidding, with five ad networks bidding in parallel. Here are my real-world numbers after three weeks of production, the SDK pitfalls, and how I delegate daily monitoring to Claude in Chrome.
◇ App Dev2026-08-16
My chart broke on day one, not at scale
A line chart that vanished for anyone with only a few days of data. The cause was a zero-height Y axis turning coordinates into NaN. Here is the measured behavior and the small normalization layer that fixed it.
◇ App Dev2026-08-15
TestFlight External Testing or Phased Release: Where a Solo Developer's Time Actually Pays Off
When you ship a Rork-built app to other people, you can recruit external testers or let a phased release absorb the risk. Here is how I split my limited time between the two, based on where distribution actually stalls and which three areas still deserve pre-release checks.