Publisher Independence
Floor price optimization: a floor strategy for first-price auctions
Published · Last updated
Next scheduled review:
A floor price is the lowest bid a seller will accept for an impression. In first-price auctions, floor price optimization means setting floors high enough to stop buyers' shading models from underpaying, but low enough to keep fill. This page covers hard and soft floors, dynamic floors, Prebid and Google Ad Manager rules, and how to test them.
Contents
Key facts
- Google told publishers to rethink floors in 2019. When Ad Manager moved to a first-price auction, Google said floor tactics built for second-price auctions "will no longer be relevant". Floors should instead reflect "the true value" of inventory (Google, 10 May 2019).
- Ad Manager allows up to 200 pricing rules per network. When two rules overlap, the higher price applies, and floors are compared with the bid after Google's revenue share is removed (Google Ad Manager Help, pricing rules, accessed 9 November 2026).
- Prebid has a built-in way to test floors. The Price Floors module's
skipRateswitches all floor logic off for a random share of auctions, so you can compare floored and unfloored traffic (Prebid.org, Price Floors module). - Reserve prices raised revenue in a large field test. A randomised experiment on Yahoo's sponsored search auctions found revenues "increased substantially" after reserve prices were set using optimal auction theory (Ostrovsky and Schwarz, Journal of Political Economy, 2023).
- Prices jumped when sellers moved to first price, then faded. Publishers that switched saw revenue per sold impression rise 25% to 70%, with the gain tending to dissipate over time (Goke et al., arXiv, 2021).
Definition
Floor price (reserve price): a minimum price, set by the seller for an impression or a group of impressions, below which no bid can win. In OpenRTB it travels as imp.bidfloor, as duration floors for video and audio, or as a deal floor. See the glossary entry for floor price.
Economists call it a reserve price. Roger Myerson showed in 1981 that a seller facing uncertain bidders can raise expected revenue with a reserve set above its own value of the item (Myerson, Mathematics of Operations Research, 1981). The ad market adds two twists: thousands of auctions a second, and buyers whose software learns where your floor sits.
What a floor does in a first-price auction
In a second-price auction, the winner pays the runner-up's bid, so a floor mattered mostly when only one buyer bid above it. In a first-price auction, the winner pays its own bid, and buyers use bid shading to bid just above what they expect to need. A floor gives that shading model a hard lower bound. If the buyer values the impression above the floor, it bids at least the floor. If not, the impression goes unsold.
So every floor change has two effects. It lifts the price on auctions where the top buyer would have shaded below the floor but values the impression more. And it loses auctions where no buyer values the impression at the floor. The net result depends on which group is larger, and only data can tell you. The shading side of this is explained in bid shading explained.
A worked example: when raising a floor pays
Take one ad unit with 1,000,000 bid requests a month and a $1.00 floor. You consider $1.50. Split the traffic into four groups by the top shaded bid and the top buyer's true value. All figures are illustrative, built on the shading logic in bid shading explained.
5 of 5 rows
A: already above $1.50 | 600,000 | $2.20 average | Above $1.50 | $1,320 | $1,320 |
B: shaded below $1.50, value above | 200,000 | $1.20 average | Above $1.50 | $240 | $300 (bids rise to $1.50) |
C: value below $1.50 | 100,000 | $1.20 average | Below $1.50 | $120 | $0 (unsold) |
D: below $1.00 | 100,000 | Under $1.00 | Under $1.00 | $0 | $0 |
Total | 1,000,000 | $1,680; fill 90% | $1,620; fill 80% |
A: already above $1.50
- Requests
600,000
- Top bid today
$2.20 average
- Top buyer's value
Above $1.50
- Revenue at $1.00 floor
$1,320
B: shaded below $1.50, value above
- Requests
200,000
- Top bid today
$1.20 average
- Top buyer's value
Above $1.50
- Revenue at $1.00 floor
$240
C: value below $1.50
- Requests
100,000
- Top bid today
$1.20 average
- Top buyer's value
Below $1.50
- Revenue at $1.00 floor
$120
D: below $1.00
- Requests
100,000
- Top bid today
Under $1.00
- Top buyer's value
Under $1.00
- Revenue at $1.00 floor
$0
Total
- Requests
1,000,000
- Top bid today
- Top buyer's value
- Revenue at $1.00 floor
$1,680; fill 90%
Table by AdSovereign, CC BY 4.0.
Average price per sold impression, the eCPM, rises from $1.87 to $2.03. Revenue falls by $60, or 3.6%. Now shift 50,000 requests from group C to group B. At $1.00 the total is still $1,680, but at $1.50 it becomes $1,695, a gain of 0.9%, with fill rate at 85%. The same floor wins or loses money depending on a split you cannot see without testing. This is why a higher eCPM alone never proves a floor works.
Hard floors, soft floors and the other floor types
Most exchanges now run first-price auctions with hard floors. The other types still show up in contracts and ad server settings, so it helps to know what each one does.
6 of 6 rows
Hard floor | Bids below it are rejected |
|
Soft floor | Bids above it clear second price; bids between it and the hard floor pay their own bid | Legacy second-price exchanges |
Deal floor | Minimum for a private deal; with |
|
Duration floor | Floor that rises with ad length |
|
Floor set per request by a model | Prebid floor providers, Ad Manager optimized floors | |
Target CPM | Floors vary per request so the average CPM meets a target | Ad Manager pricing rules |
Hard floor
- What it does
Bids below it are rejected
- Where you meet it
imp.bidfloor, Prebid enforcement, Ad Manager pricing rules
Soft floor
- What it does
Bids above it clear second price; bids between it and the hard floor pay their own bid
- Where you meet it
Legacy second-price exchanges
Deal floor
- What it does
Minimum for a private deal; with
at3 it is the fixed deal price- Where you meet it
deal.bidfloorin OpenRTB
Duration floor
- What it does
Floor that rises with ad length
- Where you meet it
mincpmpersecordurfloorsfor video and audio
- What it does
Floor set per request by a model
- Where you meet it
Prebid floor providers, Ad Manager optimized floors
Target CPM
- What it does
Floors vary per request so the average CPM meets a target
- Where you meet it
Ad Manager pricing rules
Table by AdSovereign, CC BY 4.0.
Soft floors mix two auction types in one, which confuses buyers' shading. Microsoft's Xandr exchange documentation says soft floors "use a floor price to achieve a combination of first and second price in a single auction". It marks such auctions with at 1, because it cannot promise a second-price outcome (Microsoft Learn, Xandr bidder transparent auction FAQ, updated 21 October 2025). If you still run soft floors, expect buyers to shade as if the auction were first price.
Static and dynamic floors
A static floor is a fixed table: this ad unit, this size, this price. A dynamic floor changes with the context of each request, such as device, geography, time of day, page or bidder. Static floors are easy to audit. Dynamic floors usually earn more but need a model, a feedback loop and guardrails.
Prebid's Price Floors module supports both. Floors come from one of three "rule locations": a real-time data service (dynamic), the setConfig call (package) or the ad unit (Prebid.org, Price Floors module). Rules can use ad unit, GPT slot, media type, size and domain, and Prebid.js lets you add custom dimensions. When several rules match, the most specific one wins, with specificity weighted from the left-most field. A * acts as a catch-all.
You can build the model in-house or buy it. The Prebid documentation lists Magnite, OpenX, PubMatic, Assertive Yield, pubX and Mile as floor providers, each with its own description. One provider advertises an average revenue uplift of 22% (company claim) (Prebid.org, floors providers). Treat any such figure as a hypothesis for your own test, not as a forecast.
Prebid Price Floors: an annotated floors file
Schema 2 of the floors data lets you run two or more floor models at once and split traffic between them by weight (Prebid.org, schema 2). The file below is what a dynamic floors endpoint could return. It compares a current model with a challenger set about 10% higher, and skips floors on 10% of auctions as a no-floor control. Values are illustrative.
{
"floorsSchemaVersion": 2,
"currency": "USD",
"skipRate": 10,
"floorProvider": "in-house-yield",
"modelTimestamp": 1794182400,
"modelGroups": [
{
"modelVersion": "current-2026-11",
"modelWeight": 50,
"schema": { "fields": ["mediaType", "size", "domain"], "delimiter": "|" },
"values": {
"banner|300x250|news.example": 1.2,
"banner|728x90|news.example": 0.9,
"banner|*|*": 0.6,
"video|*|*": 6.0
},
"default": 0.4
},
{
"modelVersion": "challenger-plus10",
"modelWeight": 50,
"schema": { "fields": ["mediaType", "size", "domain"], "delimiter": "|" },
"values": {
"banner|300x250|news.example": 1.32,
"banner|728x90|news.example": 0.99,
"banner|*|*": 0.66,
"video|*|*": 6.6
},
"default": 0.44
}
]
}Enforcement is set in the page's setConfig, not in the data file. The settings below enforce floors in the browser and in Prebid Server, leave deals to the deal floor, and apply bid adjustments so floors compare net prices.
pbjs.setConfig({
floors: {
auctionDelay: 100,
floorMin: 0.25,
endpoint: { url: "https://floors.example/prebid/floors.json" },
enforcement: { enforceJS: true, enforcePBS: true, floorDeals: false, bidAdjustment: true }
}
});The floorMin value is a minimum the module never goes below, and Prebid notes it is not a way to set a static floor. The floorDeals setting defaults to false. The bidAdjustment setting defaults to true, because turning it off can signal a gross floor when a bidder expects net (Prebid.org, Price Floors module).
For server-side auctions, Prebid Server fetches and caches floor files per account, applies skipRate, and can enforce floors on only a share of auctions with enforceRate (Prebid.org, Prebid Server floors). Account-level floor files fit naturally into Prebid Server stored requests, and the wider wrapper set-up is in the Prebid.js guide.
Google Ad Manager unified pricing rules
If Google Ad Manager is your ad server, its unified pricing rules set floors for most non-guaranteed demand at once. They apply to the Open Auction, Private Auctions, First Look, Open Bidding exchanges, remnant line items, header bidding trafficking and SDK bidding. They do not apply to Programmatic Direct (Google Ad Manager Help, pricing rules).
7 of 7 rows
Limit | Up to 200 pricing rules per Ad Manager network |
Overlap | If two rules target the same inventory, the higher price applies |
Net of revenue share | A $1.00 bid on an 80/20 revenue share is worth $0.80, so a floor above $0.80 filters it |
Floor sent to buyers | The lowest floor that applies to all buyers; advertiser- or brand-specific floors are enforced but not sent |
Private Auctions | A deal-level toggle can let a deal skip pricing rules |
Ad pods in apps | The floor applies to the combined CPM of the pod |
Pricing options | Fixed floor, target CPM, or "Let Google optimize floor prices" (beta) |
Limit
- What Google's help page says
Up to 200 pricing rules per Ad Manager network
Overlap
- What Google's help page says
If two rules target the same inventory, the higher price applies
Net of revenue share
- What Google's help page says
A $1.00 bid on an 80/20 revenue share is worth $0.80, so a floor above $0.80 filters it
Floor sent to buyers
- What Google's help page says
The lowest floor that applies to all buyers; advertiser- or brand-specific floors are enforced but not sent
Private Auctions
- What Google's help page says
A deal-level toggle can let a deal skip pricing rules
Ad pods in apps
- What Google's help page says
The floor applies to the combined CPM of the pod
Pricing options
- What Google's help page says
Fixed floor, target CPM, or "Let Google optimize floor prices" (beta)
Table by AdSovereign, CC BY 4.0.
Target CPM lets Ad Manager set floors per request so that the average CPM meets your target. Google's own example shows two queries where a $2.00 floor sells one impression, while a $2.00 target sells both. eCPM falls 5% and revenue rises 95% (Google Ad Manager Help, understand target CPM). Read that as an illustration of the mechanism, not as an expected result.
Optimized floor prices, in beta on 9 November 2026, set a floor per query to maximise long-term revenue. They override overlapping rules, except advertiser- or bidder-specific floors, and only work with "Set pricing for everything" (Google Ad Manager Help, optimize floor prices). Google recommends testing them with a manual experiment and warns against overlapping experiments, which can mislead through spillover. Publishers weighing other ad servers can compare them in Google Ad Manager alternatives.
How bid shading and floors interact
Floors and shading models now train against each other. Each time a shaded bid falls below your floor, the exchange can return loss code 100, "Bid was Below Auction Floor", or 101 for a deal floor (OpenRTB 3.0, loss reason codes). Each loss notification teaches the buyer where your floor sits. If you also send the floor in imp.bidfloor, the buyer knows it before bidding.
That has two consequences. First, where competition is thin, a shading buyer will often bid just above the floor, so the floor effectively becomes the price. That is good for you if the floor is close to the buyer's value and costly if it is far below. Second, a floor that is never tested goes stale, because buyers' models keep adapting. OpenRTB also lets exchanges return the price needed to win through ${AUCTION_MIN_TO_WIN}. An exchange may leave it empty, for example when a bid did not meet the floor (OpenRTB 2.6, section 4.4.1).
Buyers read floors in a fixed order. The deal floor comes first, then the video or audio floor, then the impression floor (OpenRTB implementation guide, section 7.11). Keep the three consistent, or a buyer may bid against the wrong one. The fields themselves are covered in OpenRTB 2.6 explained.
How to run a floor experiment
Floor changes are cheap to make and easy to misread. A short, disciplined test protects you from both. These eight steps work with Prebid's skipRate and model groups, or with Ad Manager experiments.
- Pick one primary metric. Use revenue per 1,000 ad requests (RPM per request), not eCPM. It captures both price and fill.
- Set guardrails. Agree in advance the fill rate, timeout rate and user-experience limits that stop the test.
- Create a clean control. Keep a share of traffic on today's floors, plus a small no-floor group via
skipRate, so you can see what floors are doing at all. - Change one thing. Test one floor table or one model against the current one. Do not change bidders or timeouts at the same time.
- Split at random, per auction. Prebid's model weights are re-rolled every auction, so each arm sees the same mix of traffic (Prebid.org, schema 2).
- Run long enough for buyers to adapt. Shading models learn from losses. Judge the result on the later weeks, not the first days.
- Read results by segment. A floor can win on desktop and lose on mobile. Break results down by ad unit, device, geography and bidder.
- Log enough to explain the result. Keep bid-level records of floor, bids, winner, loss reasons and the model version, as described in log-level data.
5 of 5 rows
RPM per request | Revenue ÷ ad requests × 1,000 | Combines price and fill | Needs request counts from the same source as revenue |
Fill rate | Impressions ÷ ad requests | Shows lost inventory | Rises if you lower floors, whatever the revenue |
eCPM | Revenue ÷ impressions × 1,000 | Shows price paid | Rises as fill falls; misleading alone |
Bid rate | Bids ÷ bid requests, per bidder | Shows buyers walking away | Some bidders drop out quietly |
Floor loss share | Losses with code 100 ÷ all bids | Shows how often floors bind | Depends on exchanges returning loss codes |
RPM per request
- Formula
Revenue ÷ ad requests × 1,000
- Why it matters
Combines price and fill
- Trap
Needs request counts from the same source as revenue
Fill rate
- Formula
Impressions ÷ ad requests
- Why it matters
Shows lost inventory
- Trap
Rises if you lower floors, whatever the revenue
eCPM
- Formula
Revenue ÷ impressions × 1,000
- Why it matters
Shows price paid
- Trap
Rises as fill falls; misleading alone
Bid rate
- Formula
Bids ÷ bid requests, per bidder
- Why it matters
Shows buyers walking away
- Trap
Some bidders drop out quietly
Floor loss share
- Formula
Losses with code 100 ÷ all bids
- Why it matters
Shows how often floors bind
- Trap
Depends on exchanges returning loss codes
Table by AdSovereign, CC BY 4.0.
Here is how the primary metric can disagree with eCPM. Each arm sees 10,000,000 requests. The control fills 62% at a $2.10 eCPM, for $13,020 in revenue and an RPM per request of $1.302. The test fills 55% at $2.45, for $13,475 and $1.348. The test wins by 3.5% despite losing seven points of fill. Figures are illustrative; work them out with your own counts.
Floors in video and CTV
Video floors scale with ad length. OpenRTB 2.6 offers mincpmpersec, a floor per second, and durfloors, a table of floors by duration range (OpenRTB 2.6, Object: DurFloors). The specification's own example sets $5 for 1 to 15 seconds, $10 for 16 to 30 seconds and $20 above 31 seconds. A seller should use one form, not both, in the same object (OpenRTB implementation guide, section 7.11).
Ad pods change the arithmetic again. Google Ad Manager applies floors on podded app traffic to the combined CPM of the pod, so single ads can clear below the floor (Google Ad Manager Help, pricing rules). Pod mechanics are explained in SSAI and CTV ad serving.
Common mistakes
- Judging floors by eCPM. eCPM rises whenever fill falls. Use revenue per request.
- Floors that ignore revenue share. In Ad Manager, floors compare with the net bid. A floor set on gross numbers filters more than you intended.
- Forgetting deals. A deal floor below your open-market floor invites buyers to move spend into the deal. Review both together.
- Leaving
skipRateat zero forever. Without a no-floor control, you cannot tell what floors are earning. - Changing floors and bidders together. You will not know which change moved revenue.
- Overlapping rules you have not mapped. In Ad Manager the higher price wins, so an old rule can silently override a new test.
- Copying a vendor's uplift figure into a forecast. Test it on your own traffic first.
- One floor for all video lengths. A 6-second and a 30-second ad are not the same product; use duration floors.
Floor strategy is one part of yield management for independent publishers; the publisher independence hub and the RTB architecture hub link the related pages, including header bidding explained.
FAQ
What is a floor price in programmatic advertising?
bidfloor (OpenRTB 2.6).What is a good floor price?
What is the difference between a hard floor and a soft floor?
Do floors hurt fill rate?
Should floors be shared with bidders?
How this works on owned infrastructure
A floor strategy is only as good as the evidence behind it: every bid, every loss reason and every floor value the auction actually applied. When the auction runs inside someone else's platform, you see aggregated reports and a recommended floor, but not the bid curve that justifies it. AdSovereign provides an exchange and SSP, alongside DSP, DMP and clean room components, that you can deploy on your own infrastructure. Floor tables, experiment arms and bid-level logs then live in your warehouse, so the eight-step test above runs on complete data and you decide when a model goes live. The architecture page shows where the auction and its logs sit, and use cases describes the publisher set-ups this fits.
Sources
- Google, "An update on first price auctions for Google Ad Manager" (10 May 2019). https://blog.google/products/admanager/update-first-price-auctions-google-ad-manager/
- Google Ad Manager Help, "Pricing rules" (accessed 9 November 2026). https://support.google.com/admanager/answer/9298008?hl=en
- Google Ad Manager Help, "Understand target CPM" (accessed 9 November 2026). https://support.google.com/admanager/answer/10357452?hl=en
- Google Ad Manager Help, "Optimize floor prices in pricing rules (Beta)" (accessed 9 November 2026). https://support.google.com/admanager/answer/11385824?hl=en
- Prebid.org, "Module: Price Floors" (accessed 9 November 2026). https://docs.prebid.org/dev-docs/modules/floors.html
- Prebid.org, "Prebid Server Price Floors" (accessed 9 November 2026). https://docs.prebid.org/prebid-server/features/pbs-floors.html
- IAB Tech Lab, OpenRTB 2.6 specification, Objects Imp, Deal, DurFloors and section 4.4.1 (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/openrtb2.x/blob/main/2.6.md
- IAB Tech Lab, OpenRTB 2.x implementation guide, section 7.11 "Guidance on the Use of Floors" (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/openrtb2.x/blob/main/implementation.md
- IAB Tech Lab, OpenRTB 3.0 specification, "List: Loss Reason Codes". https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%20v3.0%20FINAL.md
- Microsoft Learn, "Bidder transparent auction FAQ" (Xandr documentation, updated 21 October 2025). https://learn.microsoft.com/en-us/xandr/bidders/bidder-transparent-auction-faq
More sources (3)
- M. Ostrovsky and M. Schwarz, "Reserve Prices in Internet Advertising Auctions: A Field Experiment", Journal of Political Economy 131(12), 2023 (abstract on EconPapers). https://econpapers.repec.org/RePEc:ucp:jpolec:doi:10.1086/725702
- R. B. Myerson, "Optimal Auction Design", Mathematics of Operations Research 6(1), 1981. https://doi.org/10.1287/moor.6.1.58
- S. Goke, G. Y. Weintraub, R. Mastromonaco, S. Seljan, "Bidders' Responses to Auction Format Change in Internet Display Advertising Auctions" (arXiv, 2021). https://arxiv.org/abs/2110.13814