How to serve other people’s ads on your own website — and why it is a completely different world from Google Ads.
1. The three names everyone confuses
Before anything else, we need to clear up a naming disaster. Google has three products whose names are almost identical, and mixing them up leads entire projects astray:
| Product | Who uses it | What it does |
|---|---|---|
| Google Ads | Advertisers (buy side) | You buy ad space to promote your own business on Google Search, YouTube, and partner sites. |
| Google Ads Manager Account (MCC) | Agencies & freelancers (buy side) | An umbrella login on top of Google Ads. It runs no campaigns itself — it lets an agency manage many client Google Ads accounts from one dashboard (up to 85,000 linked accounts). |
| Google Ad Manager (GAM) | Publishers (sell side) | You sell ad space. It is an ad server: it decides, in real time, which advertiser’s creative appears in each slot on your website. |
This article is about the third one: Google Ad Manager (GAM) — the platform you use when the ads on your site are not yours. You own the shelf space; advertisers rent it.
The key mental shift: in Google Ads you think in campaigns, keywords, and bids to win someone else’s audience. In GAM you think in inventory, orders, and priorities to arbitrate between advertisers competing for your audience.
2. What Google Ad Manager actually is
Picture a digital billboard in a train station, where someone decides — at the very second you look at it — which poster to display. GAM is that “someone”: an ad server. It sits on Google’s infrastructure and waits. Every time a page on your site loads with an empty ad slot, the page raises its hand and asks: “I have a free slot, what should I display?” GAM looks at every campaign that could match, applies priority rules, and answers with the winning creative — or with an empty response if nothing matches (a no-fill).
Two halves make the system work:
- GAM (server side) — the brain. Holds your inventory definitions, the campaigns (orders and line items), the creatives, and the decision logic.
- GPT (Google Publisher Tag, site side) — the mouth. A small JavaScript library (
gpt.js) embedded in your pages that describes each slot, calls GAM, and injects the returned creative into the right<div>.
GAM does nothing on its own. If GPT is not deployed on a page, that page generates zero ad requests and therefore zero impressions — no matter how perfectly the server side is configured. This is not theoretical: real-world audits regularly find sites showing 0 impressions for a whole quarter simply because the tag was never published on the production templates.
3. The building blocks (inventory model)
You describe your world to GAM with a small set of stacked bricks:
your GAM account — numeric code, e.g. 1234567
travels in every ad request
the shelves — each has an address
/1234567/SITE_TOP_BANNER↓ can be grouped into
PLACEMENTS (bundles sold together)
↓ contain
LINE ITEMS
which ad units · sizes · dates ·
priority · targeting
↓ carry
CREATIVES (image, HTML5, video)
section=politics, pageID=1234- Network — your GAM account, identified by a numeric network code. It travels inside every ad request like a postal code.
- Ad unit — one sellable slot, with a full path such as
/NETWORK_CODE/UNIT_NAME. This path is the key: the page and the server must pronounce it identically or they will not understand each other. - Placement — an optional grouping of ad units you sell as a package.
- Order + line items — an order represents a deal with one advertiser; each line item inside it says where to show (which ad units), what (sizes, creatives), when (flight dates), and how strongly (priority). A reserved “guaranteed” line beats an auction-based line.
- Creative — the visual itself (image, HTML5, third-party tag, video).
- Key-values — optional labels the page attaches to its request (“this page = politics section, id = 1234”) so line items can target or exclude finely.
⚡ TL;DR — Network > ad units (path = matching key) > placements; orders > line items (targeting + priority) > creatives; key-values refine. GAM only reacts when a page asks.
4. The life of an ad request
Here is the full round trip — the thing you must be able to replay in your head when debugging:
gpt.jsdefineSlot('/NETWORK/UNIT', [[728,90]], 'div-id')+ options:
enableSingleRequest(), consent, lazy loaddisplay('div-id') / refresh() → HTTP callsecurepubads.g.doubleclick.net/gampad/ads(unit path, sizes, key-values, consent signals)
creative returned →
GPT injects it into the
<div>empty response →
GPT collapses the
<div> (height 0)GPT performs three gestures, always in this order:
- Declare the slot —
googletag.defineSlot('/1234567/SITE_TOP', [[728,90]], 'div-gpt-top'): the exact ad unit path (same as in GAM), the accepted sizes, and the id of the HTML<div>that will host the ad. - Set options —
pubads().enableSingleRequest()(SRA), consent handling, lazy loading,collapseEmptyDivs(). - Fire —
googletag.display('div-gpt-top')(orrefresh()): only now does the real network call togampad/adsleave the browser.
The golden rule: GAM and GPT must pronounce exactly the same ad unit path. If the page asks for an address GAM doesn’t know (typo, wrong path), GAM finds nobody and returns empty. The ad fails not because the campaign is misconfigured, but because the question was badly asked. Conversely — and this trips people up — an empty response with a perfectly correct path means the blocker is on the server-side matching (expired order, size mismatch, targeting, unverified site…).
⚡ TL;DR — defineSlot (path + sizes) → options → display() = one gampad/ads request. Path must match GAM exactly. Empty answer = no line item matched; the response body tells you more than the console.
5. How GAM decides: line item types and priorities
This is where GAM differs most radically from Google Ads. In Google Ads, an auction decides everything. In GAM, you define a waterfall of priorities, and the auction only fills what your direct deals leave over.
| Line item type | Priority (default) | Typical use |
|---|---|---|
| Sponsorship | 4 | “Advertiser X owns 100% of this slot for the period” — share-of-voice deals, roadblocks, homepage takeovers |
| Standard | 6 / 8 / 10 | Classic guaranteed campaigns: deliver N impressions between two dates; GAM paces delivery automatically |
| Price Priority | 12 | Non-guaranteed: serves only if nothing above wants the impression, at a fixed price |
| Network / Bulk | 12 / 16 | Remnant fillers |
| House | 16 | Self-promotion, defaults when nothing else fills |
| AdSense / Ad Exchange backfill | dynamic | The programmatic auction competes for whatever direct sales don’t take |
Lower number = higher priority. A Sponsorship (4) line always beats a Standard (8) line, which beats programmatic backfill. This waterfall is the entire point of GAM: it lets a sales team promise “your banner will be on the homepage all of March” and guarantee it against the open auction.
Contrast with Google Ads — there is no equivalent concept on the buy side. An advertiser in Google Ads can only bid harder; a publisher in GAM can simply decree who wins.
6. Pricing: floors, Unified Pricing Rules, and what they actually control
Priorities decide who gets to serve. Pricing decides whether the impression is worth serving at all. On direct deals the price is negotiated by humans and written into the line item. On programmatic, a setting does the negotiating for you — and most publishers leave it untouched for months.
A price floor is the minimum CPM you accept. Below it, you would rather serve nothing. That sounds obvious until you realise both directions cost money:
- Floor too low — you sell your best inventory at remnant prices. Buyers have no reason to bid above a floor you never raise.
- Floor too high — the impression goes unsold. A no-fill earns exactly zero, and an empty slot also costs you the user’s attention.
Since Google moved its exchange to a unified first-price auction, the winner pays what they bid rather than one cent above the runner-up. Floors stopped being a safety net and became your main pricing lever.
6.1 Unified Pricing Rules (UPR)
UPR is where floors live in GAM today. Rather than scattering minimum CPMs across individual line items, you define pricing rules centrally and GAM applies them to programmatic demand — Ad Exchange, Open Bidding, AdSense.
Each rule can be scoped, and this is the part that matters:
| Scope | Why it matters |
|---|---|
| Ad unit / placement | Homepage masthead and archive footer should never carry the same floor |
| Format & size | A large high-impact format commands a premium; a small trailing banner does not |
| Device | Mobile and desktop have different viewability profiles, and buyers price them differently |
| Geography | Your domestic audience is usually worth more to your advertisers than incidental foreign traffic |
| Buyer / deal | You can floor open-market demand higher or lower than a named buyer on a preferred deal |
The mistake to avoid is a single site-wide floor. Your most-read section and your 404 page are not worth the same to a buyer, and a flat rule prices them identically.
6.2 Floors, targets, and letting Google optimise
A rule can express a hard floor (never sell below this) or a target CPM that GAM optimises around. Google also offers an optimised-pricing option that adjusts floors automatically using its own demand signals.
Automation is fine, on one condition: know what you handed over. An automatically-optimised floor maximises Google’s view of your yield, which is closely correlated with yours — not identical to it. Keep at least one segment on a manual floor as a control group, so you can tell whether optimisation is actually earning its keep.
Practical rule: revisit floors on a schedule, not when revenue drops. Demand is seasonal; your settings are not. A floor nobody has touched in a year is not a strategy, it is an oversight that bills you every month.
7. Configuration points, end to end
The practical checklist for setting up a GAM network, in the order that avoids rework.
7.1 Network level (Admin → Global settings)
- Note your network code — it will prefix every ad unit path.
- Time zone and currency (affects flight dates and reporting).
- User access: invite traffickers/admins with appropriate roles (Administrator, Trafficker, Salesperson, Report-only…).
7.2 Inventory
- Ad units (Inventory → Ad units): create one per slot template, with clear hierarchical naming (
SITE_SECTION_POSITION, e.g.NEWS_HOME_TOP_BANNER). Avoid a flat list of units with typos — inconsistent naming (“LATTERAL” vs “LATERAL”) is a real-world classic that poisons trafficking forever. - Sizes: prefer standard IAB formats (300×250, 728×90, 970×250, 320×50, 300×600). Exotic in-house sizes (1000×123, 1800×800…) work for direct deals but are incompatible with programmatic demand.
- Placements: group units you sell as bundles.
- Sites (Inventory → Sites): declare and verify every domain that will request ads. Verification typically relies on your
ads.txtfile or a tag. An unverified site sits with a “Needs attention” badge, and unrecognized domains are a documented cause of chronic no-fill even for reserved campaigns. - ads.txt: publish
https://yourdomain.com/ads.txtlisting your authorized sellers. For pure direct-sold setups there may be no AdSensepub-ID to list (that ID only exists if you use AdSense/AdX) — but the file still matters for site verification and becomes mandatory the day you open programmatic. An ads.txt containing a wrong publisher ID is worse than an empty one.
7.3 Tagging (the site side)
- Generate GPT tags per ad unit, or hand-write them:
gpt.jsin<head>,defineSlot+ a<div>per slot, onedisplay()per slot. - Deploy on the real production templates — via hardcoding or a GTM custom HTML tag. Either works; hardcoding is often more robust for ad slots, while measurement tags (GA4, CMP) live comfortably in GTM. What matters is that someone actually publishes it — an unpublished tag means zero requests forever.
- SRA (Single Request Architecture):
enableSingleRequest()sends all the page’s slots in one call — required for roadblocks (guaranteeing competing ads don’t share a page) and better for consistency. collapseEmptyDivs()so no-fills don’t leave white holes.- Lazy loading for below-the-fold slots — a direct lever on viewability (moving from ~35% to 60%+ viewability changes what your inventory is worth).
- Key-values: send structured context (
site,section,pageID…) withsetTargeting(). Define the keys in GAM first (Inventory → Key-values).
7.4 Privacy and consent (not optional in the EEA)
- Install a CMP (Consent Management Platform) certified for IAB TCF v2.3 (Didomi, Axeptio, Sourcepoint…). Without a TCF consent string, requests fall back to limited/non-personalized modes (
npa=1,ltd=1), which crushes CPMs (personalized demand typically pays 3–5× more) and can restrict serving altogether for EEA traffic. - Configure Privacy & messaging → European regulations at the network level — a brand-new network has nothing configured there, and that gap combined with consentless test traffic is a classic hidden blocker.
- Make sure your test pages carry the CMP too, or your tests will run in a different consent mode than production and mislead you.
7.5 Trafficking a campaign (the daily workflow)
- Order — create one per advertiser deal (advertiser, salesperson, dates).
- Line item — choose type/priority, flight dates, goal (impressions or %), rate, then targeting: ad units and/or placements, geography, device, key-values. Two silent killers to double-check:
- End date: an expired order stops serving everywhere, instantly — the #1 cause of “the ads suddenly disappeared”.
- Key-value exclusions: a line excluding
pageID = Xis harmless while no page sendspageID, and becomes a bomb the day the site starts sending it.
- Creatives — upload one per booked size. A size declared in the page’s
defineSlotbut missing from the line item’s creatives = no match for that request (GAM only considers creatives matching the requested sizes during selection). - Preview and check delivery after launch (see §10).
7.6 Opening up to programmatic (when ready)
- AdSense backfill — one checkbox per ad unit; fills unsold impressions with the AdSense auction. Zero risk, modest revenue.
- Ad Exchange (AdX) — Google’s premium exchange (requires eligibility/GAM 360 or an MCM partner); real-time competition from many buyers.
- Header bidding (Prebid.js) — external exchanges bid before the GAM call; their bids enter GAM as key-values matched by price-priority line items.
- Open Bidding — Google’s server-side equivalent.
- Set real rates on direct line items (even informational): a system where every deal is booked at €0 gives you reports with impressions but no revenue visibility.
8. Direct sold vs programmatic — the two revenue engines
price: as negotiated
AdX / Open Bidding / Prebid
or 🏠 house ad / collapse (no-fill)
| Direct sold | Programmatic | |
|---|---|---|
| Who sells | Your sales team, human negotiation | Automated auction |
| Pricing | Fixed (CPM/CPD/flat), agreed offline | Dynamic, per impression |
| Booking | Orders + line items, manually trafficked | Demand connects via AdX/Prebid |
| Formats | Anything you agree on (including custom sizes) | Standard IAB sizes only, in practice |
| Guarantee | Yes (Sponsorship/Standard) | No |
| Typical role | Premium inventory, brand deals | Fill the remnant, price discovery |
Mature publishers run both: direct deals take the premium slots at guaranteed prices, programmatic monetizes everything left over.
9. Open Bidding vs header bidding: where the auction actually happens
Section 8 said programmatic fills what direct sales leave over. But “programmatic” is not one pipe — and the difference between the two main options is not about price, it is about where the auction runs and who runs it.
9.1 Header bidding (Prebid)
The auction happens before the ad server is called. A wrapper — usually Prebid.js — asks several exchanges for a bid, collects the answers, and passes the winning price into GAM as key-values. Line items configured in price buckets then compete against your direct campaigns on equal footing.
You own the code, the timeout, and the partner list. You also own the latency and the maintenance.
9.2 Open Bidding
The auction happens inside Google’s stack, server-side. Third-party exchanges are invited into the Ad Exchange auction and GAM arbitrates the whole thing in one call. Setup is a configuration screen rather than a JavaScript deployment.
Simpler, faster on the page — and Google takes a fee for running it, on an auction whose internals you observe rather than control.
| Header bidding (Prebid) | Open Bidding | |
|---|---|---|
| Where the auction runs | In the browser (or your own server wrapper), before the GAM call | Server-side, inside Google’s stack |
| Who operates it | You | |
| Page latency | Adds a measurable delay you must cap with a timeout | Minimal — one call |
| Setup & upkeep | Real engineering work, ongoing | Configuration in the GAM UI |
| Transparency | You see every bid response | You see the outcome, not the mechanics |
| Cost | Your engineering time | A fee on transactions Google clears |
In practice, plenty of publishers run both: Open Bidding for the demand that is easy to plug in, header bidding for the partners they want to control directly. What you should never do is run the same exchange in both paths and let it bid against itself — you pay the latency twice and gain nothing.
The question to ask is not “which pays more this month”. It is: how much engineering time can I sustainably spend on ad infrastructure? Header bidding rewards teams that maintain it. Open Bidding rewards teams that cannot.
10. Debugging: the toolkit that actually works
GAM ships with excellent diagnostic tools; knowing them turns week-long mysteries into 5-minute checks.
Google Publisher Console — append ?google_console=1 (or ?googfc) to any page URL that loads GPT. A debug panel opens showing every slot, its unit path, the request status, and fill/no-fill per slot. Crucial detail: it only activates if the page already loads gpt.js — on an untagged page the parameter does nothing (which is itself a diagnostic: no console = no GPT = no requests). It works on production pages; it is a viewer, it changes nothing.
The Network tab — find the gampad/ads request. Read iu= (the requested unit path) and the sizes, and compare against GAM. A 200 OK with a tiny/empty body is a no-fill (Google’s docs: 200 = “an ad OR a blank response was returned”). An empty body with a correct iu means the blocker is server-side matching, not the tag. Also read the consent params: npa=1, rdp=1, ltd=1 = the request went out in limited-ads mode without TCF consent.
Delivery Tools → Inspect webpage ads — GAM’s native inspector: give it a URL and the line item you expect, and it returns Google’s official verdict (e.g. “Line item not found — the line item is not targeting as expected or is not serving”), plus a per-dimension targeting breakdown.
Ad Request Simulator — replays an exact captured request against the ad server and lists which line items were candidates. If your line is absent from the candidate pool while its targeting looks right, the block is upstream of the line item (site recognition, consent, network-level).
Line item → Troubleshoot tab — shows delivery causes (“line item always delivers, no non-delivery reasons”) and creative render rates.
Reports — a Domain × Ad server impressions report instantly reveals whether a site has ever served (a domain at 0 impressions over a quarter = chronic, structural problem, not a recent regression).
Field-tested failure catalogue
Real causes of “the ads don’t show”, roughly ordered by how often they bite:
- GPT never deployed on production templates — the site emits zero requests. Symptom: no
gpt.js, nogampad/adsin the Network tab. Beware static<img>banners hardcoded in the CMS that look like ad serving but generate 0 GAM impressions. - Order/line item expired — everything worked yesterday, empty responses today, on every domain at once. Check flight end dates first.
- Ad unit path mismatch — typo or wrong network code in
defineSlot. - Size mismatch — the page requests sizes the line item has no creative for.
- Site not declared/verified in Inventory → Sites — reserved campaigns can be blocked on unrecognized domains; the “Needs attention” badge means verification is incomplete (often because
ads.txtis missing or wrong). - ads.txt with a wrong publisher ID — worse than absent; blocks domain trust.
- Consent chain broken — no CMP/TCF on the page →
ltd=1limited mode → EEA demand restricted, CPMs crushed. - Key-value exclusion trap — an exclusion that was dormant activates when the site starts sending that key.
- Test page vs production divergence — the test page has GPT but no CMP, production has CMP but different tags; you end up debugging a configuration that exists nowhere.
Method note: debug by differential. Compare a working page and a failing page captured at the same time (same request minutes). One variable at a time; every hypothesis must survive a hard proof (HAR capture, UI screenshot, official Delivery Tools verdict) before you act on it.
11. Ad request ≠ impression ≠ viewable impression
Three numbers that get used interchangeably in meetings, and are not the same measurement at all. Every reporting argument in this industry starts here.
| Metric | What it means | What it does not mean |
|---|---|---|
| Ad request | The browser asked for an ad | That an ad came back. No demand, floor too high or targeting unmet all end in a no-fill |
| Impression | A creative was returned and began rendering | That anyone saw it. It may be 2,000 pixels below the fold in a background tab |
| Viewable impression | The ad met the MRC threshold on screen | That the user looked at it, or remembered it |
The MRC standard — the industry reference for viewability — requires at least 50% of the ad’s pixels on screen for at least one continuous second for standard display. Video needs two continuous seconds. Very large display formats are held to 30% of pixels for one second, on the reasoning that they cannot fit on a small screen at all.
Between the first number and the last, there is mechanical leakage. That is not a fault to fix: it is the web working normally. Users scroll away, tabs stay in the background, connections drop mid-load.
Two consequences worth internalising:
- “We do 4M impressions” is a meaningless sentence until someone says which of the three numbers that is. Fix the vocabulary before you negotiate anything.
- Lazy loading moves the numbers in opposite directions. Requesting ads only as they approach the viewport cuts your raw impression count and lifts your viewability rate. Tuned well, revenue rises. Tuned aggressively, you fire the request too late, the ad arrives after the user has scrolled past, and you lose on both counts.
Before optimising anything, get everyone — sales, tech, and the client — to agree on the unit of measurement. That single conversation prevents most of what follows.
12. Why your numbers and the advertiser’s never match
Sooner or later an advertiser tells you they counted 12% fewer impressions than you billed. They are not lying, and neither are you. You are running two different measurement systems and comparing the outputs as if they were the same instrument.
12.1 Where the gap comes from
- Different counting points. Your ad server and the buyer’s platform start counting at different moments in the delivery chain. Every step between them loses events.
- Different fraud filters. Each side applies its own invalid-traffic detection, with its own lists and thresholds. What you count as legitimate can be discarded downstream.
- Different time zones. Two tools on two zones do not cut the same day. On daily reporting, that alone produces a visible gap that disappears over a full month.
- Latency and abandonment. A user who leaves mid-load may be counted on one side and not the other.
- Redirects and wrappers. Every additional hop in the creative chain is another opportunity to lose the beacon.
12.2 What is normal, and what is a bug
A discrepancy in the region of 10% is the industry’s working assumption between an ad server and a buy-side platform. Uncomfortable, structural, and not worth a war.
Beyond that, stop arguing and go looking for a specific cause:
- a duplicated tag firing twice on the same slot
- lazy loading requesting ads the user never reaches
- a redirect chain breaking the third-party counter
- a creative that fails to execute its own tracking on some browsers
- consent gating that blocks the buyer’s pixel but not your ad server
12.3 The only durable fix
The right answer is never “our numbers are the correct ones”. It is contractual: name one source of truth for billing before the campaign starts, and write down the tolerated variance. Publishers who do this spend zero hours per quarter on reconciliation calls. Publishers who do not, spend a great many.
13. KPIs: publisher metrics vs advertiser metrics
Another deep difference with Google Ads. Advertisers optimize acquisition cost; publishers optimize yield.
| Google Ads (advertiser) | Google Ad Manager (publisher) |
|---|---|
| Impressions, CTR | Ad server impressions, per domain/unit/advertiser |
| CPC — what a click costs you | eCPM — what 1,000 impressions earn you |
| CPA / ROAS — cost per result | Fill rate — % of requests that returned an ad |
| Quality Score | Viewability (% of impressions actually seen — target 60%+) |
| Impression share (auction) | Delivery/pacing — is a guaranteed line on track for its goal? |
| Conversion volume | Programmatic vs direct revenue split |
A publisher’s daily dashboard: impressions by site and unit, fill rate, eCPM by demand channel, viewability, and delivery health of guaranteed lines.
14. Reporting: Query Tool vs Data Transfer
GAM gives you two very different ways to look at your own business, and choosing the wrong one is why some publishers can explain their revenue and others can only describe it.
14.1 The Query Tool answers “how much”
Built into the GAM interface, it produces aggregated reports: impressions, clicks, eCPM, fill rate, viewability — sliced by date, ad unit, order, line item, advertiser or key-value. Reports can be scheduled and pulled through the API.
For daily steering, this is enough. It tells you what happened.
14.2 Data Transfer answers “why”
Data Transfer delivers raw, event-level files — one row per request, impression, click and activity — to cloud storage, where you load them into a warehouse. It is a GAM 360 feature, and it changes what questions you are able to ask:
- reconcile ad impressions against GA4 sessions on the same page view
- explain a discrepancy against an advertiser’s platform, event by event
- analyse yield by key-value combination rather than by ad unit
- rebuild a full funnel in BigQuery and expose it in Looker Studio
- keep history beyond the retention window of the reporting UI
14.3 Why it matters more than it sounds
Aggregated data lets you observe a problem. Only event-level data lets you explain it. The distinction becomes concrete the first time an advertiser disputes an invoice, or the first time revenue drops 8% and nothing in the interface says why.
A dashboard that never drills down to the raw event will only ever confirm what you already believed.
15. GAM vs GAM 360: where the free tier stops
Google Ad Manager has a free tier that does considerably more than most people expect, and a paid tier called Google Ad Manager 360. The interesting question is not what each contains, but what actually forces the move.
The free tier handles inventory, direct sales, the full priority waterfall, basic programmatic and standard reporting. For a mid-sized publisher, it is genuinely sufficient.
Constraints appear on three fronts:
| Front | What the free tier limits |
|---|---|
| Volume | A monthly impression ceiling. Above it, Google expects you to move to 360 |
| Features | Part of the advanced programmatic, multi-network and inventory-management capability is reserved for 360 |
| Data | The one that usually decides it: no Data Transfer, shorter reporting history, less analytical granularity |
Google sets and periodically revises the volume ceiling, so check the current figure rather than trusting a number you read in a blog post — including this one.
The real trigger is almost never traffic. It is the day you can no longer explain your own numbers: an advertiser disputes an invoice, a client asks for performance by audience segment, or your yield drops and the interface offers no answer.
While you sell volume, the free tier is fine. The day you start selling performance, you need to be able to prove it — and proof lives in the data layer.
16. Quick-start checklist
- ☐ Network: code noted, timezone/currency set, users invited
- ☐ Ad units created with clean hierarchical naming, IAB sizes
- ☐ All domains declared and verified in Inventory → Sites
- ☐
ads.txtpublished and correct on every domain - ☐ GPT deployed on production templates (verified in the Network tab:
gpt.js+gampad/adspresent) - ☐ SRA +
collapseEmptyDivs+ lazy loading configured - ☐ CMP (IAB TCF v2.3) live on production and test pages; European regulations configured in Privacy & messaging
- ☐ First order + line item + creatives for every booked size; end dates sane
- ☐ Test with
?google_console=1; confirm fill on a real article page - ☐ Reporting: domain-level impression report scheduled; rates set to real values
- ☐ Runbook written: “ads not showing” → Publisher Console → Network tab → Delivery Tools → Simulator
17. Summary
Google Ads spends money to place your ads on other people’s screens. Google Ad Manager earns money by orchestrating other people’s ads on your screens — a server-side brain (network, ad units, orders, line items, creatives) paired with an on-page mouth (GPT) that must pronounce the exact same ad unit paths. Its superpower over any auction-only system is the priority waterfall: guaranteed direct deals always beat programmatic backfill. Its fragility is the number of silent single points of failure — an unpublished tag, an expired order, an unverified domain, a missing consent string — each of which produces the same symptom: an empty slot. Configure the foundations in order (inventory → sites/ads.txt → tags → consent → campaigns → programmatic), and learn the four debug tools; they turn every empty slot from a mystery into a diagnosis.