◉RORK LABJP
●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●RORK — GPT-6.1 Sol (Sep 29) and Claude Sonnet 5.5 (Sep 28) are now in the model menu●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 2 days left●Q&A — People keep asking why AuthSession returns no result in Android standalone builds●WINDOWS — A walkthrough shows how to ship an iPhone app from Windows only, with no Mac●NEW — When only notifications fail in Expo Go: three checks to run first●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●RORK — GPT-6.1 Sol (Sep 29) and Claude Sonnet 5.5 (Sep 28) are now in the model menu●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 2 days left●Q&A — People keep asking why AuthSession returns no result in Android standalone builds●WINDOWS — A walkthrough shows how to ship an iPhone app from Windows only, with no Mac●NEW — When only notifications fail in Expo Go: three checks to run first
Articles/Business
⟐ Business/2026-09-06Advanced

Your Blended eCPM Dropped and Revenue Went Up: Splitting the Change Into Country Mix and Rate

Blended eCPM is a weighted average, not a price. Here is how I split a month-over-month change into a country-mix effect and a rate effect that reconcile exactly to the total, plus what to check before you cut a low-eCPM country.

AdMob71eCPM5Revenue AnalysisIndie Development26Rork577

✦ Premium Article

One morning I opened the dashboard and the number at the top was lower than the month before. Blended eCPM had fallen by about a quarter.

I went straight to the country report and sorted by unit price, ascending. I was looking for countries to cut. Two candidates showed up within a couple of minutes.

Then I noticed that the estimated payout further down the same screen was higher than the previous month.

The average was down and the money was up. One of the two had to be wrong, so I spent two days pulling the report apart. What was wrong turned out to be the way I was reading it.

Blended eCPM is a weighted average, not a price

The blended eCPM in the AdMob console is revenue divided by impressions, times 1,000. Written out, it is each country's eCPM weighted by that country's share of impressions.

Which means it moves for two entirely separate reasons.

  1. Unit prices themselves changed (rate effect)
  2. Impression shares shifted between countries (mix effect)

The awkward part is that the second one alone can move the average a long way. If impressions grow in a low-price country, blended eCPM falls even when not a single country's price has changed. And because impressions grew, revenue rises.

I was sorting as if I were looking at the first case. What had actually happened was the second. Running a few apps in parallel as an indie developer, I hit this mix-up roughly once a season, because the countries where organic installs grow fastest tend to be the low-price ones.

A unit price is a number for comparing, not a number for deciding what to switch off. Open a country report without that line drawn and you walk straight toward the decision that shrinks revenue.

Splitting the change with no residual

There are several ways to do factor decomposition. For something I run every month, my requirement is that the two effects add up to the total change exactly. A decomposition that leaves a residual stops being trusted by the second month.

The simplest form that satisfies this uses symmetric averages. With r as a country's eCPM, w as its impression share, 0 for the prior period and 1 for the current one:

EffectFormulaHow to read it
RateΣ (r1 − r0) × (w0 + w1) / 2How far the average would have moved on price changes alone, had the mix held still
MixΣ (w1 − w0) × (r0 + r1) / 2How far the average would have moved on share changes alone, had prices held still

Add the two and you get the change in blended eCPM exactly. The interaction term is split evenly between the two sides rather than being shoved into one of them.

The one case you have to decide on is a country that exists in only one of the periods. A newly served country has no prior price. Treating its price as unchanged and pushing its entire contribution into the mix side is what matches reality: the average moved because impressions appeared there, not because a price changed.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You will be able to tell whether a move in blended eCPM came from your country mix or from actual unit prices, using nothing but the country report you already have
✦Before you cut traffic from a low-eCPM country, you will be able to check in a few minutes whether that country is merely dragging the average down or genuinely carrying revenue
✦You will have a 60-line script that decomposes a country CSV into mix and rate contributions and reconciles exactly to the total change, ready to drop into your monthly routine
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
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 $15 for lifetime access
View Membership →

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.
⟐ Business2026-05-03
From Rork to $1,000/month with AdMob — A Practical Indie Developer's Monetization Playbook
How to take a Rork-built mobile app toward meaningful monthly AdMob revenue: category fit, getting the ATT-before-initialize order right, time-based interstitial pacing, judging by ARPDAU, app-ads.txt, and running a small portfolio.
⟐ Business2026-05-02
A Solo Developer's Strategy for Pushing a Mobile App Past ¥100k/Month — Real Revenue Tuning Tested on Rork-Built Apps
The hands-on strategy for breaking the ¥100k/month wall in solo mobile development. Ad eCPM optimization, IAP tuning, subscription retention, and ASO — every lever I've actually tested on Rork-built apps over 12 years of solo monetization, with code and numbers.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links