Analyzing the Bid Landscape: How to Price Your Premium Ad Inventory
In December 2025, Google removed unified pricing rules from Ad Manager, renamed the feature pricing rules, and gave publishers a control the stack had never allowed: a floor price aimed at one specific programmatic bidder while every other bidder competes without it. Floor pricing is now a set of small, testable decisions rather than one global number. Each decision still rests on the question publishers have faced since the 2019 first-price transition: what is this impression worth, and what happens to fill when I insist on that price?
Where the old bid report went
Ad Exchange once answered that question with a dedicated report that compared bids in 0.10 dollar increments. Google has deprecated it: new data no longer appears, and historical data remained viewable for six months after deprecation, which gives that dataset a hard expiry. The report carried two structural limits worth remembering, because they explain why your own logs beat it anyway. The 0.10 dollar increments blurred the exact range where premium inventory trades; a distribution that cannot tell $4.10 from $4.20 cannot tune a floor between the two. And some buyers chose not to reveal their bid data, so the published distribution always understated real demand. Treat the report as retired context, not a tool to reach for. The distribution you price against today comes from your own auction: ad server delivery logs, BigQuery exports of OpenRTB traffic, Prebid analytics adapters, and clearing data from your demand partners.
A floor behaves differently in first price
Google moved Ad Manager to first-price auctions in 2019 and set out its original floor guidance in the same announcement. The guidance retired a whole category of tactics: floor price strategies created to influence the second-price auction closing no longer matter, because in first price the winner pays its own bid. In second price, a floor mostly moved what the winner paid; in first price the floor is a disclosed minimum that buyers shade their bids toward, so it sets what the winner pays directly. Google's advice amounted to one instruction: focus on the true value of the inventory rather than on mechanical manipulation of the auction. The same announcement introduced unified pricing rules with an initial limit of 100 rules, and at launch Google applied every floor to all partners equally. From 2019 until December 2025, that equal application defined the ceiling of floor strategy: you could not push the bidder that always clears at the bottom of your auction without pushing every other bidder at the same time.
What the rules engine does with your floors
Google's documentation on optimized floor prices states the tradeoff plainly: setting a floor price too high risks impressions going unfilled, leaving potential revenue on the table. The mechanics behind that warning are predictable in first price. Buyers read the floor from the bid request and shade their bids to sit just above it, so every raise converts into a higher clearing price until the buyers who value the placement below the floor stop bidding. Past that point, each cent of floor buys empty impressions instead of revenue.
Two behaviors in the rules engine decide what happens when your floors collide. Optimized floor prices override floors from overlapping pricing rules, so one optimized rule beats every static floor that covers the same query. And when two overlapping optimized rules exist, Google attributes the query to the rule created first, which turns creation order into a priority system. Build accordingly: create the optimized rule you want to win before anything it might overlap, and write the order down, because the next person to edit these rules needs to know which one wins.
Per-bidder floors turn pricing into experiments
The December 2025 removal of unified pricing rules changes what a floor can target. Google renamed the feature pricing rules and enabled floor prices for specific programmatic bidders, so a floor no longer has to hit every bidder at once. Three configurations now earn their setup time on premium inventory:
- Differential protection: hold open-market bidders to a high floor on the placements you sell as premium packages, while negotiated partners clear at the prices in their deal.
- Pressure on chronic low bidders: raise the floor on the seat that always clears at the bottom of the auction; if it carries real budget it pays more, and if it does not, its bids were its ceiling and you have learned that.
- Elasticity testing: move one bidder's floor in fixed increments, hold everything else constant, and read the response from that bidder's own bid distribution instead of guessing at its budget.
Each configuration only works with per-bidder clearing data, which is exactly what the retired report used to approximate and what your own logs now provide. Build the per-bidder view first, then decide which of the three configurations fits the data.
Where floors sit relative to direct demand
A floor only prices the demand that competes in the open auction. Sponsorship and standard line items with higher priority take impressions before open-market bidders ever see them, so a floor never reprices a sold package; it prices the impressions the package leaves unsold. That division of labor suits premium inventory. The direct deal holds the price it negotiated, and the floor keeps the unsold remainder from trading at a discount that undermines the package rate in the next negotiation.
Two consequences follow. Floors on premium placements protect rate integrity, not just yield: a sponsor paying a premium rate should never discover that the same slot trades at a fraction of it whenever the sponsorship lapses. And the floor test needs the direct pipeline in view: when a sponsorship ends, the clearing distribution changes shape overnight, and a floor tuned to the old shape sits in the wrong place.
What the buyer sees: bidfloor and bidfloorcur
Every floor, wherever you set it, reaches the buyer as fields in the OpenRTB bid request. The OpenRTB 2.6 spec defines bidfloor as the minimum bid for this impression expressed in CPM, and bidfloorcur as the currency in ISO 4217 alpha codes; the spec defaults are 0 and USD, per Google's Authorized Buyers OpenRTB reference. The defaults do damage when you ignore them. A request without bidfloor tells the buyer there is no minimum, and a floor configured in a non-USD currency without a matching bidfloorcur reads as US dollars: a EUR 4.00 floor arrives as a $4.00 floor, and the conversion gap reprices the impression without anyone noticing.
Audit the currency on every seat, especially server-side seats where a partner passes your floor through its own conversion. The field also carries information beyond the number: bidfloor discloses your reserve to every buyer in the request, and in first price buyers shade toward it, so the floor operates as a published price suggestion rather than a hidden guardrail. Set floors you could defend in a direct negotiation, because that is functionally what you are doing.
A floor also has two enforcement points, and conflating them wastes demand. Request time is the first: bidfloor travels in the bid request and the buyer enforces it against itself, which is where shading happens. Auction time is the second: the Prebid floors module and Ad Manager pricing rules each re-check bids against the enforced floor, so a buyer that clears the signaled floor but not the enforced one still gets rejected. Keep the signaled floor and the enforced floor aligned; when they drift apart, buyers spend budget on bids that die quietly inside your auction.
The path of a floor through the stack explains where pricing mistakes enter: a rule in Ad Manager or a floors file in Prebid becomes the bidfloor field in an OpenRTB request, the buyer shades against it, the module rejects any bid below it, and the ad server line item the bid maps to depends on your price granularity. Most pricing errors live at these handoffs, not in the number you chose.

Client-side floors and price granularity
Prebid enforces its floors before bids reach the ad server. The Price Floors Module marks all bids below the floor as "bids rejected", and that status is measurable: analytics adapters report rejection rates per bidder, which tells you which buyers had headroom above your floor and which ones the floor priced out entirely. The Prebid maintainers do not recommend static floors, and their wording deserves the quote: static floors are "blunt tools you will forget to update." The module fetches floor data from an endpoint you control instead, and that data can vary by media type, size, domain and bidder, which is the resolution per-bidder pricing needs on the client side.
Price granularity is the other half of the Prebid pricing problem. Header bids must map to discrete line items in the ad server, so the auction can only distinguish bids at the resolution of your buckets, and Prebid quantizes bids accordingly. Prebid's own guidance sets the cap around the 95th percentile bid and places finer buckets where popular bid values cluster. Test whatever bucket scheme you inherited against your own distribution: the cap belongs near your 95th percentile, and the fine increments belong where your bids actually cluster, which on premium placements is the top of the range, not the bottom.
A working method for premium placements
The analysis reduces to one distribution per placement per bidder: how often each price level wins. Build it from ad server delivery logs or a BigQuery export of OpenRTB requests and responses, and read percentiles rather than averages. An average clearing price of $4.00 can describe a placement where half the impressions clear near $2.50 and half near $5.50; a single floor set at that average fails both halves. Premium placements typically show a fat top tail from direct-demand pressure and a long low tail from open-market fill, and the floor has to sit relative to the tail you want to keep.
Test floors in small increments against that distribution. Raise the floor by roughly 10 percent of the median clearing price, hold the change for a full week to absorb daypart and campaign-flight noise, and measure revenue per impression rather than CPM. CPM rises mechanically with the floor, because buyers shade upward to the disclosed minimum; revenue falls once buyers below the floor drop out faster than the price rises. The arithmetic fits in a spreadsheet, and running it once by hand teaches the shape of the curve better than any dashboard.
Not every placement deserves a floor test. If one buyer dominates a placement, the floor works as a price list rather than an auction instrument: the buyer accepts it or walks, so move in smaller steps and watch that buyer's bid distribution instead of the average. Floors also cannot manufacture demand; when the distribution tops out, an aspirational floor simply empties the slot. Price the inventory you have, then decide which placements justify the work.
The worked example below shows the pattern on one premium placement: a 300x600 slot in a section with direct advertiser pressure, 100,000 monthly impressions, no sponsorship attached. Revenue equals impressions times fill rate times clearing CPM, divided by 1,000.
| Floor | Fill rate | Average clearing CPM | Revenue on 100,000 impressions |
|---|---|---|---|
| No floor | 99% | $3.70 | $366.30 |
| $3.00 | 96% | $3.88 | $372.48 |
| $3.50 | 94% | $4.05 | $380.70 |
| $4.00 | 89% | $4.20 | $373.80 |
| $4.50 | 71% | $4.55 | $323.05 |
| $5.00 | 43% | $5.10 | $219.30 |
The curve peaks at a $3.50 floor, about 5 percent below the $3.70 no-floor average clearing price, right where fill has barely moved and shading has already lifted the clearing CPM. The intuitive anchor, a floor set at the average clearing price, sits to the right of the peak and gives up the difference. Past $4.00 the fill collapse dominates: the two 50-cent steps to $5.00 trade away 18 and then 28 points of fill for 50 cents of clearing price each. What fills behind a rejected impression decides the true cost of a high floor: if the impression cascades to a house ad, the loss is the full programmatic price.

Per-bidder floors sharpen the same test. Run the curve separately for the seat that clears at the bottom of your auction and the seat that clears at the top, and you stop averaging away the differences the December 2025 change exists to exploit.
How much of the discovered value you capture depends on how the auction treats bids after the floor has done its work. In first price, a buyer that shades toward your disclosed floor submits a bid shaped by the floor rather than by its full valuation, and an auction that ranks face value rewards the wrong behavior. How our auction ranks bids closes that gap: expected-value ranking with first-price bid shading, plus reserve prices and goal-based pacing, so the floor sets the entry price and the ranking prices each bid for what it will actually pay.
How we run this stack
We are OnlyMedia, an ad network, an SSP and an agency in one company, and we run this exact pricing work for thousands of publishers in our publisher network, each above one million monthly pageviews. The sell side runs one unified auction per impression: AdX access through MCM, Prebid for header and server-side demand, and OpenRTB 2.6 seats for buyers that connect directly, all inside our SSP. We maintain managed floors against live clearing data, which means the distribution analysis, the floor tests and the per-bidder rules run continuously rather than once a quarter.
The commercial terms stay fixed so the pricing math stays honest: we pay publishers Net 30, CPM based, no chasing, no sliding terms. A floor that wins on paper has to show up in a payment on schedule, or the test result means nothing. When a publisher cannot verify a price improvement inside one payment cycle, the improvement does not exist.
A pricing review on a schedule
The clearing distribution moves with every flight, every seasonal shift and every new seat, so premium pricing needs a calendar rather than a crisis. A cadence that holds up in production:
- Weekly: check Prebid rejection rates per bidder and fill rate per premium placement; a rejection rate that jumps means a buyer's bids moved and your floor did not.
- Monthly: rebuild the clearing distribution per placement and per bidder from logs, and confirm the price granularity cap still sits near the 95th percentile bid.
- Quarterly: re-run the floor curve on your top placements, re-check pricing rule creation order, and delete rules that overlap an optimized rule they cannot beat.
- On every seat change: reset that bidder's floor test, because shading behavior does not carry over to a new integration.
Agencies advising publishers should treat each item as an auditable deliverable rather than a verbal assurance: the floor curve, the rule list in creation order, and the rejection-rate trend are artifacts a client can inspect. Floors price what the data supports, and the data moves first. The publishers who hold premium pricing re-run the curve before the fill report tells them to.
To see the same work priced against your inventory before committing internal hours, email us for a revenue estimate and we will size what managed floors and per-bidder pricing would return on your placements. The estimate arrives by email, priced by the same team that runs the auctions.