AdTech · Spring 2026

How sellers set floors without killing win rate.

A practical guide to setting per-request floor prices in Prebid + GAM without collapsing fill rate: where the trade-off actually lives, why static floors burn demand, and how session-aware FPO lifts revenue per request.

Vasco Reid, Tiago SantosMay 3, 20267 min read1,564 wordsFiled under AdTech
Floor_Price_Optimization_AdTech
Floor_Price_Optimization_AdTech

Floor pricing is the lever publishers reach for first when they want to lift CPM, and it's the lever that costs them the most when used wrong. Push reserve prices too aggressively and win rate, fill rate, and demand-partner trust all move in the wrong direction. Leave them too low and revenue leaks on every request. The hard part is that there is no single right answer — the right floor depends on the request, the user, the bidder, and the auction history.

This guide walks the question every publisher and SSP has to answer: how do you set floors that lift revenue per request without collapsing win rate? We cover where the trade-off actually lives, why a Prebid + Google Ad Manager (GAM) hybrid is the safest place to test higher floors, why demand partners push back when you over-floor, and the session-aware approach published in the TensorOps paper Recapturing the English Auction. For the conceptual primer that sits underneath this playbook, see What Is Floor Price Optimization in Programmatic Advertising?.

Why floor pricing got harder after the move to first-price

In the waterfall era, floors were a per-network static decision and the cost of getting one wrong was small — a network either filled or it didn't, and the next one in line picked up the slack. Header bidding (Prebid) and first-price auctions collapsed that into a single sealed-bid round per impression. Every request now needs its own reserve price, computed in real time, with no second chance.

Two failure modes follow directly from that change. Set the floor above the highest bid and the impression goes unfilled — you lose revenue you would have captured at any positive price. Set the floor below the bidder's true willingness-to-pay and you accept a bid that undervalues the inventory. Both happen on every mis-priced request, and at scale the gap between them is the entire revenue surface you can optimize.

Floor Price Optimization (FPO) exists because the answer is no longer a static rule — it's a model. The job of a floor pricing system is to put a number on each request that's high enough to extract competitive bids and low enough that it doesn't drive bidders out of the auction.

Fill rate vs CPM — the FPO frontier sits above any static floor Fig. 01 · Fill rate vs CPM A static floor traces one curve. A per-request, session-aware floor traces a structurally higher one. 50% 60% 70% 80% 90% 100% $0 $1 $2 $3 $4 $5 $6 Fill rate Average CPM healthy fill · 75–90% Static floor FPO · per-request +RPR at same fill Optimization target is revenue per request (RPR = CPM × win rate), not either axis alone

What is the actual trade-off between fill rate and CPM?

Higher floors raise CPM on the impressions you fill and lower the count of impressions you fill. Lower floors do the inverse. The optimization target is neither number in isolation — it's revenue per request (RPR), which is CPM multiplied by win rate. RPR is what actually lands in the publisher's account.

A few rules of thumb that hold across most publisher inventory:

  • Static floors set on aggregate historical CPM almost always over-floor the long tail and under-floor the head. The best static floor is still measurably worse than a per-request dynamic floor.
  • Healthy fill rate sits in the 75–90% range. Below 70% means floors are eating fill that wouldn't have been replaced; above 95% means CPM is being left on the table.
  • Win-rate compression on a specific bidder is the early signal that you've over-floored for them specifically. Watch per-bidder win rates, not just the aggregate.

Aggressive static floors push you off the efficient frontier — a few cents of CPM gain costs more in unfilled impressions than it earns in the cleared ones. Dynamic floors raise the floor only when the live signal supports it and relax it when competition is thin.

How does your stack constrain the floors you can actually set?

Most publishers run floors through GAM Unified Pricing Rules (UPR). UPR is fine for broad rule-based pricing — geo, device, ad unit, advertiser bucket — but it cannot run a per-request model with session state. For real dynamic floors, the floor decision has to move into Prebid.

The hybrid that works in production:

  1. Prebid runs first with dynamic per-request floors, passed transparently to bidders via imp.bidfloor in OpenRTB.
  2. GAM gets the Prebid winner as the price to beat. If GAM has stronger direct or AdX demand, it wins.
  3. If GAM doesn't beat the Prebid winner, the Prebid bid wins. No fillable impression is lost to the higher Prebid floor.
Prebid runs first with dynamic floors; GAM gets the winner as the price to beat Fig. 02 · Prebid + GAM hybrid Push the floor decision into Prebid. GAM still gets a chance to beat the Prebid winner — no fillable impression is lost to a higher Prebid floor. Ad request + session features Dynamic floor model per-request · session-aware Prebid auction imp.bidfloor · OpenRTB winning bid → price to beat GAM · UPR + AdX direct + open-market demand GAM beats it GAM bid wins GAM doesn't Prebid bid wins Worst case for a too-aggressive Prebid floor: you fall back to GAM's own pricing logic — no impression is silently dropped

That hybrid is what makes higher floors safe to test — the worst case is a fallback to GAM's pricing logic. The Prebid Price Floors Module is the supported entry point; for true session-aware per-request floors, an integration like the TensorOps Prebid Adapter replaces the static module with a model that updates as the session unfolds.

Why demand partners push back when you over-floor

Demand partners measure their side of the relationship on CPA, ROAS, installs, registrations, first-time deposits — outcomes, not the CPM they paid. Push the floor above the price at which their model breaks even on those outcomes and the response is predictable: budgets shift to cheaper supply, bid shading gets more aggressive, your inventory gets throttled.

The endgame of over-flooring is the worst combination of all three problems at once: high floors, low fill rate, and a reputation as expensive supply for the quality. Walking that back takes months and sometimes never fully recovers — bidders carry memory of how a publisher has priced them in the past, and that memory shows up in future bid shading. The same pressure shows up on the buy side: see What Is Supply Path Optimization in Programmatic Advertising? for the mirror dynamic where DSPs consolidate spend on the cleanest, cheapest paths to the same impression.

Lifting inventory value without lifting floors

The publishers who win at floor pricing rarely win by being more aggressive — they win by making the inventory worth more before any floor is applied. The mechanism is data: richer first-party signals about the user, surfaced in a structured way to demand partners.

  • First-party behavioral and engagement signals — pages-per-session, recurrence, time-on-site, declared interests — turned into stable identifiers bidders can match against their targeting lists.
  • DMP integration so DSPs can identify users already on their high-value segments at bid time and price the request accordingly.
  • Session context — referral source, content category, prior exposures — surfaced in the bid request so bidders score the impression instead of guessing.

Done well, this lifts the bid distribution itself. The floor stays where it was; the bids it filters against are higher. Worth pairing with budget pacing on the buyer side — pacing-constrained bidders are more sensitive to floor moves than steady spenders, so the floor model and the pacing model interact in ways aggregate dashboards hide. The information-asymmetry angle is covered in the TensorOps paper Toward Information Symmetry: A Bilateral Disclosure Framework for First-Price Ad Auctions.

Recapturing the English auction with session data

The most concrete public work on session-aware floors is the TensorOps paper Recapturing the English Auction: Sequential Floor Optimization Within User Sessions in Programmatic Advertising. The framing is straightforward — a single user session is structurally an iterative English-style auction across many requests, not a series of independent sealed-bid rounds. Treat it that way and information from earlier requests becomes input to pricing the later ones.

The model has two phases:

  1. Opening floor — predict the initial floor from pre-session features (geo, device, URL, time of day, traffic source) before any bids have been observed.
  2. Real-time recalibration — after each ad request, update the floor with a bias-corrected exponential moving average over in-session signals: previous bids, response patterns, exposures so far in the session.

Reported simulation results from the paper:

  • +27% revenue per request vs. a no-floor baseline.
  • +3.4% vs. a tuned static floor.
  • The FPO yield curve sits structurally above any static-floor curve at comparable fill rates — a different frontier, not a better point on the same one.

A working playbook for setting floors

  1. Move the floor decision out of GAM UPR and into Prebid. Keep UPR for broad pricing buckets; use Prebid for the per-request number.
  2. Run Prebid + GAM as a hybrid so the higher Prebid floor never costs a fillable GAM impression.
  3. Pick a model with session memory, not aggregate daily statistics. The English-auction framing is the cleanest published version of this.
  4. Track per-bidder win rate and CPA, not just aggregate fill and CPM. Pull back floors on any bidder whose CPA spikes.
  5. Lift inventory value in parallel — first-party data, DMP integration, session context in the bid request — so the bid distribution moves up, not just the cutoff against it.

Floor pricing is a model, not a price

What makes modern floor pricing work is treating the floor as the output of a model trained on your specific traffic, your specific bidders, and the live state of the current session — not as a number in a config file. Done that way, floors lift CPM and protect fill at the same time. Done the old way, they buy short-term CPM at the cost of long-term demand.

TensorOps builds floor optimization systems for publishers, SSPs, and resellers — including the Prebid-integrated, session-aware FPO behind the English-auction framework. If your floors still live in GAM UPR or in a static daily file, that's where the next 5–10% of yield is. The full research catalogue is at TensorOps Labs, and the team is at tensorops.ai/contact.

End.   Set in Fraunces, Newsreader & JetBrains Mono.
TensorOps · Blog · 2026