Yield · 18 Aug 2026

Dynamic floors that do not starve fill

A floor is a signal, not a guarantee. Used badly, it empties the auction. Used well, it stops you giving inventory away — without tanking volume.

Yield desk reviewing geo-level floor and fill dashboards
Floors should move with the market you actually sell — not a single global number.

Bid floors are one of the most powerful — and most misused — controls in programmatic. A floor tells buyers the minimum CPM you will accept. Set it well and eCPM rises. Set it blindly and fill collapses, timeouts climb, and your “higher eCPM” is an average over fewer impressions that may net less total revenue.

This guide is for yield managers, ad ops leads, and engineers who run OpenRTB, Prebid, or tag-based monetization. We cover how dynamic floors work, how to split rules by geo and format, what to watch in reporting, and how to roll back bad changes without panic.

Hard floors vs dynamic floors

A hard floor is a fixed minimum bid (e.g. $1.00 CPM globally). Simple to explain, easy to break in markets where demand clears lower.

A dynamic floor adjusts based on recent clearing prices — median wins, fill trends, or ML signals from the SSP. The floor chases the market instead of guessing a round number in a spreadsheet.

Most mature publishers use a hybrid: hard floors on premium placements (homepage takeover, US desktop 728×90), dynamic or soft floors on long-tail remnant.

Why global floors fail

Hard global floors look tidy in a dashboard and often fail in the countries and formats that actually need demand. A $2.50 floor that works on US desktop display can wipe an in-app 300×250 in a price-sensitive geo. The floor did not “protect yield”. It removed the auction.

Common failure modes:

  • One floor for web and app — different buyers, different clearing prices
  • One floor for interstitial and banner — interstitial usually clears higher; banners starve first
  • ROW bucket hiding India, Southeast Asia, and LATAM in one average
  • Raising the floor after one good day of brand spend that never repeats

Start from clearing prices, not a round number

Use a lookback on winning prices by geo, device, and size. Set the floor a notch under the median win — not at the 90th percentile. The 90th percentile is what a few campaigns paid on a good day. The median is closer to what the market will repeat tomorrow.

Refresh the lookback often enough that a demand mix change shows up, but not so often that a quiet Tuesday rewrites Thursday’s floor. Seven to fourteen days is a workable window for most mid-size publishers. High-volume apps can go shorter if the sample is still statistically useful.

Example workflow

  1. Pull wins for placement X, geo IN, size 320×50, last 14 days
  2. Calculate median clearing CPM (e.g. $0.42)
  3. Set floor at 85–90% of median (e.g. $0.36–0.38)
  4. Monitor fill and revenue for 48 hours
  5. If fill drops >5 points with no eCPM gain, roll back that slice only

Split where the demand mix is different

App interstitial is not the same market as a 300×250 on a content page. CTV pods are not display. If you only have one floor object, you are averaging unlike auctions into a number that is wrong for both sides.

Geo splits matter more than most teams admit. A single “ROW” bucket hides the markets where you still have buyers. Split the geos that actually contribute volume; leave the long tail on a conservative default until you have enough wins to price them.

Suggested minimum splits once you have data:

  • US, UK, DE, CA (often higher CPM)
  • India, Brazil, Indonesia (volume, different curves)
  • Long tail — default floor until N > 10k impressions/week

Deals vs open auction floors

Private marketplace (PMP) deals and preferred lines often bypass open auction floors — or use deal-specific minimums. Do not set open auction floors so high that guaranteed demand looks cheaper than it is, and do not let open auction undercut committed deal rates.

Priority order should be documented: direct deals → PMP → open auction with dynamic floor.

Do not raise the floor on every retry

Refresh rules that increment the floor on each retry train buyers to skip the placement. The second and third pass should compete on remaining demand, not on a higher reservation price. If you use a refresh, keep the floor stable or step it down slightly so leftover demand can still clear.

Ad refresh can lift impressions per page view, but greedy floor ramps on each refresh reduce bid rates over time — DSPs learn the slot is overpriced on pass 2 and 3.

Watch fill when you move a floor

If fill drops more than a few points after a floor change, roll it back on that slice only. Do not unwind the whole site because one size in one country failed. The goal is paid impressions that clear — not a pretty eCPM on a shrinking volume.

Metrics to watch together (never eCPM alone):

  • Fill rate — % of requests that receive a paid ad
  • eCPM — revenue per 1,000 impressions
  • Total revenue — eCPM × impressions; the product matters
  • Timeout rate — high timeouts can look like low fill
  • Win rate by bidder — did you price out one DSP?

Dynamic floors and OpenRTB / Prebid

In OpenRTB, floors appear in the imp.bidfloor field per impression object. Prebid adapters can pass a floor param per ad unit. Server-side floor optimization can set bidfloor per request before it hits demand — useful when client-side floors are stale.

Amli Media’s publisher tools apply floor rules per placement and geo, then show fill and eCPM on the same cut so ops is not guessing from a blended report. See publisher monetization and integration docs.

Rule of thumb: Optimize for revenue, not eCPM. A $1.20 eCPM at 40% fill often loses to $0.85 at 75% fill on the same placement.

FAQ

What is a dynamic bid floor?

A dynamic bid floor adjusts automatically based on recent clearing prices, fill, or optimization signals — instead of staying fixed until someone manually changes it.

Should I use the same floor for video and display?

No. Video and CTV usually clear higher but have different fill curves. Split by format and measure each separately.

← All posts · Integration docs · What is eCPM?