Why ad revenue drops: four metrics, five questions
Google AdSense defines page RPM as estimated earnings divided by page views, times 1,000. Ad servers start counting at the ad request, so a page view whose ad code never runs is invisible to them.
| Metric | How it is calculated | What it hides |
|---|---|---|
| Page RPM | estimated earnings ÷ page views × 1,000 | page views where the ad code never ran |
| eCPM | revenue ÷ impressions × 1,000 | unfilled requests, slots per page |
| Fill rate | impressions ÷ ad requests | page views that never sent a request |
| Viewable rate | viewable ÷ measurable impressions | impressions that could not be measured |
Counted further down the chain, the same money gives a higher CPM, so eCPM can rise while revenue falls. Keep revenue per page view, with page views from your analytics, as the headline; page RPM is that figure as your ad platform sees it. AdSense's help says it is retiring session metrics from September 2025.
- Did page views fall? Compare with the same week last year to separate season from loss.
- Did fill rate fall? Look by ad unit and size. Floors set too high and slow auctions come first. Fix it in Fill rate Header bidding
- Did eCPM fall while fill held? Check the calendar, then the viewable rate by placement. Fix it in Viewability
- Did slots per page fall? A template change, or lazy loading that never fires on short visits, removes impressions quietly. Fix it in Layout and speed
- Did revenue fall while all of that held? Fewer page views send ad requests: check ad code errors, consent and ads.txt, then the page views with an ad blocker. Fix it in Consent Blocked page views
Change one thing at a time, or you will not know which change did it.
Viewability: get the impressions you serve seen
Under the Media Rating Council standard, a display ad is viewable when at least 50% of its pixels are on screen, in an active tab, for one continuous second after it renders. Video needs two continuous seconds of play, and units of 242,500 pixels or more, such as a 970x250, may count at 30%. Google's Active View applies the same rules, the 30% one to large ads on desktop.
pixels on screen
continuous time
viewable
In an active tab, after the ad renders.
What moves it, in Google's own guidance:
- Position. Just above the fold beats the very top, and content that holds attention is seen most.
- Lazy loading with margin. Request below-the-fold ads as their slot approaches, early enough to render before the reader arrives; load above-the-fold slots first.
- Speed and measurability. Faster pages and fewer passbacks raise viewability; an ad hidden with CSS on load, or in a cross-domain iframe, can become unmeasurable.
Viewability by format
| Format | Why it tends to be seen | The limit |
|---|---|---|
| Anchor or sticky | stays on screen; Google lists anchor as highly viewable | no more than 30% of the screen under the Better Ads Standards |
| Vertical, such as 160x600, at the side | the most viewable sizes in Google's data; below the fold, side beats centre | sidebars drop below the content on many mobile templates |
| Interstitial or vignette | Google lists vignette as highly viewable | mobile prestitials fail the Better Ads Standards |
| Video player | two-second bar | Google's undated help figures: 73% of video ads above the fold are viewable, 45% below |
Fill rate: why requests come back empty
In Google Ad Manager, fill rate is impressions divided by ad requests; an unfilled impression is a request that came back with no eligible ad. Check two causes first. Floors above what your audience clears: misconfigured pricing rules can lower fill, Google warns, and a floor that suits your strongest country is often too high for the rest, so segment it. And thin demand: with one buyer, many requests find nobody, which is what header bidding addresses.
- Page views
- requests per page view Ad requests
- fill rate Impressions
- viewable rate Viewable impressions
Page views that never send a request sit outside the fill rate.
A page view whose ad code never loads sends no request, so it sits in neither half of the fraction: a site can lose page views before the auction and still report a healthy fill rate. Late calls show up elsewhere too: bids that miss the timeout are dropped, and an ad server call held too long loses the impression rather than leaving it unfilled.
Header bidding vs waterfall: how your inventory is sold
A waterfall offers each impression to demand sources one after another, in a fixed order, until one accepts. Header bidding asks several at once, before the ad server call; in the usual setup the ad server still picks the winner. Since 2019 Google Ad Manager has run one first-price auction where header bidding line items compete with Google's demand.
Waterfall // one at a time
Header bidding // all at once
timeoutThe waterfall stops at the third source; in header bidding the late bid misses the timeout.
Prebid.js is free, open-source software, launched in 2015: it calls bidders in parallel and drops late bids. Its documentation names two failure modes, bids lost to the timeout and impressions lost while the ad server waits, and suggests reading timeouts by bidder and region. It gives no number of partners: add them one at a time and keep those whose wins pay for the wait.
Ad refresh: when it pays and what the policies allow
Ad refresh requests a new ad for a slot already on the page. Whether you may do it depends on the platform.
| Rule | AdSense | Google Ad Manager |
|---|---|---|
| Timed refresh | not allowed | allowed if you declare the inventory that refreshes |
| Minimum interval | does not apply | 30 seconds on the web, for timed or event refresh |
| User action | a page or element may refresh only when the user requests it | being active, or scrolling that brings no substantially new content, is not a user action |
Sources: AdSense placement policies and Ad Manager's refresh declaration. Google restricts some buyer demand on declared inventory, says longer intervals attract buyers and prefers user-action or event refresh.
- in view
- off screen
- hidden tab
A mark in a hidden tab cannot count as viewable, and one off screen only counts if the reader scrolls back; Google's tag guidance is to refresh slots that are in view.
In practice, refresh only has room on long sessions. Judge it on revenue per session against a period without it, not on impressions or eCPM.
Layout, ad density and Core Web Vitals
- Density. The Coalition for Better Ads, from research with more than 150,000 consumers, fails mobile pages where ads exceed 30% of the main content's height, sticky units included, and desktop pages above 50%. Google bans its ads on failing screens, and Chrome can filter ads on a failing site after at least 30 days' notice.
- Layout shift. web.dev names ads among the largest sources of layout shift. Reserve each slot's space with a CSS min-height and do not collapse it when no ad fills.
- Core Web Vitals. Targets: LCP within 2.5 seconds, INP of 200 ms or less, CLS of 0.1 or less, at the 75th percentile. Google ties them to Search, not to CPM, so treat speed as a viewability and traffic lever.
Reserved the text stays where it is
Not reserved the ad arrives and pushes the text down
Ad density limit // share of the main content's height
30% mobile 50% desktop
Consent and limited ads in Europe
If you have readers in the EEA, the UK or Switzerland, consent is a revenue lever too. Since 16 January 2024 Google requires a certified CMP integrated with the IAB Europe TCF to serve personalised ads in the EEA and the UK, and in Switzerland since 31 July 2024. TC strings generated from 1 March 2026 must be TCF v2.3. Without valid signals a request can fall back to limited ads, with no audience targeting or remarketing, which Google says may affect revenue.
EEA, UK and Switzerland
- a certified CMP
- TCF v2.3 consent strings
- limited ads when the signal is missing
Everywhere else
- Google's certified CMP requirement does not apply
- check fill and price by country first
Third-party cookies have not gone away: in April 2025 Google decided to keep them in Chrome, with the choice in the user's settings. Read EEA, UK and Swiss traffic apart in your reports. Whether adblock detection is legal is a separate question.
The page views that never reach the auction
Every lever above works on page views where your ad code loads. Ad blocking removes page views from that set before any ad request is sent. Blockthrough's July 2022 report measured 21% of page views with an ad blocker, across more than 10 billion page views on 9,453 sites (adblock statistics). Your share depends on your audience, so measure it.
Page views on your site
Page views that send an ad request blocked before the request
Your ad server only counts the second bar.
This is the part we work on. AntiAdBlock Core detects page views with a blocker and shows a wall that asks the reader to allow ads on your site; the free plan covers 5,000 detections a month, with no payment method. The dashboard estimates recovered revenue at the CPM you set (adblock revenue recovery); confirm it in your AdSense or Ad Manager impressions. More in adblock rate and recovered revenue and adblock recovery methods.
Every lever, ordered by effort and risk
Start at the top, cheap and reversible: one lever at a time, a full week each, compared on the same weekdays.
Risk high
09
07
Risk medium
03 06
05
08
Risk low
01 02
04
Effort low Effort medium Effort highEach number is a row of the table below. Start in the low-low corner.
| Lever | Effort · risk | Limit | Source |
|---|---|---|---|
| Check ads.txt, consent and page views without ad requests | low · low | Google listed in your ads.txt; server logs against ad requests | Google Publisher Policies |
| Reserve slot space | low · low | an empty gap when nothing fills | Google Publisher Tag |
| Lazy load below the fold | low · medium | too tight a margin loses impressions | Google Publisher Tag |
| Move units in the content | medium · low | ad density | Google Ad Manager |
| Segment floors | medium · medium | bad rules lower fill | Google Ad Manager |
| Ask blocked readers to allow ads, with a wall | low · medium | some readers leave instead; the wall shows from the first blocked page | AntiAdBlock Core |
| Viewable, declared refresh | medium · high | not on AdSense; 30 s on Ad Manager | Google Ad Manager |
| Header bidding, few partners | high · medium | latency | Prebid.org |
| More slots | low · high | 30% of content height on mobile, 50% on desktop | Coalition for Better Ads |
Frequently asked questions
What is the fastest way to increase ad revenue on a website?
Find the weakest link first: compare page views, fill rate, eCPM and viewable rate with last year. Then the cheap checks: ads.txt, consent, reserved slot space, lazy loading, and server logs against ad requests.
Is header bidding worth it for a small site?
Prebid gives no minimum traffic; what weighs is upkeep and latency. Prebid.js is free, but every partner is another call that can time out: start with few and add them one at a time.
Why is my fill rate fine but my revenue down?
Fill rate only counts ad requests. If revenue per page view falls while fill holds, check eCPM and viewable rate by placement, then page views where your ad code never loads, such as blocked ones.
Do ad blockers show up as unfilled impressions?
Usually not. Ad Manager counts an unfilled impression only when an ad request comes back empty. If a blocker stops your ad code before the request, nothing is logged: the page view is missing, not unfilled.
How many ads can I put on a page?
There is no fixed count. The Better Ads Standards cap ad density, the share of the main content's height that ads take, with one limit for mobile and one for desktop (layout and density).
Measure the link your reports leave out
Your ad server only sees page views that send an ad request. Install the detection tag and see how many arrive with a blocker, how many readers allow your ads and an estimate of what that is worth at your CPM.
No payment method needed. Paid plans from $5 a month.
By the AntiAdBlock Core team · Updated