Blog

Bid Floors: How to Set Them, and How to Tell If They Worked

Raising a floor always raises your average CPM, even when it destroys revenue. A guide to price floors in first-price auctions, and to measuring them honestly.

16 min read By the Floxis engineering team

Raising a floor removes the cheapest impressions from the average, so average CPM rises while total revenue falls — the survivorship effect that makes floor changes look successful

An exchange raises its floors. The next morning, average CPM is up 18%.

Everybody involved reads this as a win, because it looks exactly like one. But the floor did not make anyone bid more. It removed the impressions that would have cleared cheaply from the pool, and an average computed over what remains is higher by construction. Fill fell at the same time. Whether total revenue went up or down is a different question, and the CPM chart cannot answer it — not partially, not directionally, not at all.

This is the central difficulty with price floors: the most visible metric moves the right way whether or not the change worked. A lever that reliably produces evidence of its own success is a lever that will be pushed for years without anyone noticing it stopped paying.

This article is about setting floors sensibly, and about the measurement discipline that separates a floor strategy that earns money from one that only looks like it does.

Table of Contents

What is a bid floor?

A bid floor is the minimum price a seller will accept for an impression, communicated to buyers in the bid request itself. In OpenRTB it is imp.bidfloor, with imp.bidfloorcur naming the currency — a per-impression field, so it can differ by placement, by format, by geography, or by whatever else the seller wants to price on.

Its purpose is to stop inventory clearing below what the seller believes it is worth. That belief is doing a lot of work in the sentence, and everything difficult about floors follows from it: the seller is asserting a valuation, in advance, on an impression whose actual value is only revealed by the auction they are constraining.

Two things worth being precise about, because both get muddled.

A floor is not a reserve price in the classical auction sense. In a second-price auction a reserve raises what the winner pays without changing who wins — that is the textbook result. Almost nothing in programmatic runs second-price anymore, so the textbook intuition transfers badly.

And a floor is a filter, not a negotiation. A buyer whose valuation sits below your floor does not counter-offer. They do not bid. The impression is simply gone from their consideration, and if you never see the bid you never learn how close it was.

Hard floors, soft floors, and what first-price auctions did to both

The distinction mattered enormously and now mostly does not, but it survives in interfaces and conversations, so it is worth resolving.

A hard floor is absolute: bids below it are rejected. A soft floor was a second-price artifact — bids below it could still win, but the winner paid their own bid rather than the second price plus increment. The soft floor was a way of saying “below this, you lose the second-price discount,” which gave buyers a reason to bid above it without foreclosing the impression.

First-price auctions removed the mechanism the soft floor depended on. When the winner pays what they bid, there is no discount to withhold, and a soft floor degenerates into either a hard floor or a suggestion. If your platform still exposes both, the operationally honest reading is that only the hard floor does anything, and any behaviour attributed to the soft one deserves verification before it is relied on.

The deeper consequence is that first-price auctions changed what a floor is. Under second-price, the buyer bid their true valuation and the mechanism protected them from overpaying, so a floor mostly moved the clearing price. Under first-price, the buyer bids what they are willing to pay after their own optimization, and your floor is an input to that optimization rather than a constraint applied afterwards. You are no longer setting a reserve. You are sending a signal into someone else’s pricing model — which is the subject of two sections from here.

Why is the average CPM so misleading?

This deserves its own section because it is the single most common reason floor strategies survive without working.

Consider a thousand impressions that would clear at a range of prices — some at $0.30, some at $1.20, some at $4.00. Now set a floor at $1.00. Everything that would have cleared below a dollar does not clear at all. The impressions that remain were always the expensive ones, so the average price of what sold rises sharply.

Nothing about that rise means a buyer paid more for anything. It is survivorship: you changed the population being averaged, not the prices within it.

The metric that answers the actual question is revenue per request — total revenue divided by total requests, including the ones that did not fill. That denominator is the whole point. It cannot be gamed by removing cheap impressions, because the requests you refused stay in it.

The same trap has variants worth recognizing:

  • Fill rate falls when floors rise, and is read as a cost worth paying. But fill rate has the same problem in the other direction — it says nothing about the value of what filled.
  • Win rate per demand partner shifts because partners have different price distributions. A floor change can look like a partner “improving” when you have only removed their cheapest inventory.
  • Revenue over a period moves for a dozen reasons at once — seasonality, a campaign launching, a supply partner changing volume. Comparing this week to last week attributes all of it to your floor change.

If you take one operational habit from this article: put revenue per request on the dashboard next to CPM, and never evaluate a floor change on CPM alone.

The three ways a floor loses you money

The impression does not clear at all. The obvious one. A floor above what any buyer will pay converts a low-value impression into a zero-value impression. If the alternative to a $0.20 clear is an unfilled slot, the floor cost you twenty cents — and unfilled inventory has no consolation prize.

The buyer stops asking. This is the expensive one, and it is invisible on the day you make the change. DSPs maintain their own view of which supply is worth spending infrastructure on. Inventory that consistently fails to clear becomes inventory they deprioritize, throttle, or stop bidding on — and that decision does not reverse when you lower the floor back. You have taught a buyer that your supply does not clear, and the lesson outlives the experiment. This is the same dynamic as supply path optimization operating at the placement level rather than the path level.

The floor is right on average and wrong everywhere. A floor set from an aggregate is applied to a distribution. If your inventory clears anywhere between $0.20 and $4.00 and you set a floor at the mean, you have priced out most of the bottom half while leaving everything in the top half underpriced. Aggregate floors are a way of being wrong in both directions simultaneously, and the aggregate metrics will show it as roughly neutral.

Bid shading: the buyer is optimizing against your floor

Any account of floors that ignores bid shading is describing an auction that no longer exists.

When first-price auctions became standard, buyers faced an immediate problem: bidding true valuation means overpaying every time you win. The industry response was bid shading — DSPs and their partners predict the minimum needed to win and bid near that instead of at valuation. It is now standard on essentially all meaningful programmatic spend.

For floors, this changes the game in two directions at once.

Your floor is an input to their model. A shading algorithm knows your floor because you sent it, and the cheapest way to win an impression it wants is to bid at or barely above the floor. This is why raising floors sometimes produces an immediate, clean increase in clearing prices on inventory that keeps filling — the buyer wanted it anyway and simply recalculated the minimum. That is a real gain, and it is where floor optimization earns its reputation.

And your floor is a hurdle their model will decline. The same algorithm, on an impression valued below your floor, does not bid at all. So the identical change produces gains on inventory the buyer values above the floor and total losses on inventory below it. The net depends entirely on how your inventory’s value distribution sits relative to where you put the floor — which is a property of your traffic, not a property of floors.

This is the mechanism behind the most important practical fact in this article: floor optimization results do not transfer between exchanges. A strategy that produced real gains on one platform’s inventory mix can be revenue-negative on yours, not because it was implemented wrong, but because the distribution it was tuned against is not your distribution. Any vendor quoting an uplift figure from someone else’s traffic is quoting a number with no predictive value for yours.

How to actually set a floor

A practical sequence, in order of how much it pays.

Start from observed clearing prices, not from what you think the inventory is worth. You have the data: bids received per placement, per format, per geography, per demand partner. The distribution of winning bids on a placement over the last few weeks tells you what the market says it is worth. Your opinion is a hypothesis; the distribution is evidence.

Segment before you set. Floors belong at the finest granularity where you have enough volume to estimate a distribution — usually placement by format by broad geography. A platform-wide floor is almost always wrong, and a per-request floor computed from three observations is noise dressed as precision. The judgment is where the volume runs out.

Set low and move up. The failure modes are asymmetric. A floor set too low costs you the margin between what cleared and what could have; a floor set too high costs you the whole impression plus the buyer’s future attention. Approach from below.

Change one thing at a time. Floors interact with everything — traffic shaping, partner routing, timeout configuration. A floor change shipped alongside a routing change produces one result and two candidate explanations.

Leave a holdout in place permanently. Not for the duration of a test. Permanently. Distributions drift, buyers change their shading, your supply mix changes, and a floor that paid in March can be costing money in September with nothing in your metrics to indicate it. A standing holdout is the only instrument that notices.

Dynamic floors: what they promise and what they deliver

Dynamic floor optimization — floors computed per request from recent bid history, usually with machine learning attached — is the premium tier of most yield products. The pitch is straightforward and correct in principle: floors should reflect the specific value of the specific impression, and no human can maintain that by hand across millions of segments.

The mechanics are ordinary statistics rather than anything exotic. Group impressions into segments, estimate the distribution of what buyers pay in each, pick a percentile, apply it as the floor, update as new data arrives. This is a well-understood problem and the algorithms work.

The honest caveats are three, and vendors are quiet about all of them.

The gains are bounded by how much your floors are currently wrong. If your manual floors are already near the market distribution, an optimizer has nothing to recover. The largest wins from dynamic floors come from replacing badly-set static floors, which means the headline case study is usually measuring the first fix, not the ongoing value.

Segment granularity is limited by volume, not by algorithm. Estimating a price distribution needs observations. Long-tail placements — which are most placements — never accumulate enough, so in practice they fall back to a broader segment’s floor. The per-impression precision in the pitch applies mostly to inventory that was already easy to price.

The optimizer is learning from an auction that is learning from it. Your floors shape the bids you observe, and you set floors from observed bids. Left unchecked this feeds back on itself — floors drift upward, cheap bids disappear from the training data, the model concludes the segment is expensive. A holdout is what breaks the loop, because it keeps a slice of unconstrained observations flowing.

None of this makes dynamic floors a bad idea. It makes them a lever that must be measured on your own traffic, with the ability to be switched off.

What a holdout actually requires

A holdout is a randomly selected slice of eligible traffic on which the lever is not applied, running continuously alongside the treated traffic, compared on revenue per request.

Four requirements, each of which is routinely violated:

Randomize at the right unit. Split on something stable and arbitrary — a hash of the request, of the placement, of the user. Splitting by supply partner, by geography, or by time of day does not produce comparable groups, it produces two different populations and a meaningless comparison.

Run both arms simultaneously. Before-and-after is not a holdout. Demand changes daily, and a week-over-week comparison attributes every market movement to your change. Both arms must experience the same market.

Compare revenue per request. Not CPM, not fill, not total revenue. The denominator must include the requests the floor refused.

Size it for the noise. Programmatic revenue is heavy-tailed — a small number of high-value impressions dominate the total, so short tests are dominated by whether a few big wins landed in one arm or the other. If a lever’s true effect is a couple of percent, distinguishing it from noise takes real volume and real patience. Most floor “results” reported after three days are noise.

And one design rule that outranks all four: build the off switch first. A lever that cannot be disabled for a slice of traffic cannot be measured, ever, by anyone. If you are building floor optimization, the holdout is not a testing feature to add later — it is the only thing that will ever tell you whether the rest of it works.

What we measured on our own traffic

We built adaptive floor logic into our own exchange, and we built the holdout with it. Then we ran it against live traffic on multiple demand partners.

On the partners we tested, the result came back marginal to negative — the floor lever did not produce a reliable revenue-per-request gain, and on some traffic it cost money. So we did not ship it as a default-on revenue feature. It stays available, off by default, measured per tenant.

Two reasons for publishing this rather than quietly leaving it out.

The first is that it is the most useful thing we know about floors. The result was not a bug and it was not a failed implementation — it is what a well-behaved lever looks like when a market has already priced the inventory reasonably. Buyers shade toward the floor when they want the impression and decline when they do not; if your floors are roughly where the market is, moving them mostly reshuffles which impressions clear. The gains available are real but bounded, and they are much smaller than the industry’s marketing implies.

The second is what it says about everyone quoting a number. We could have run the same experiment, reported the CPM increase, and produced an impressive figure that was true and meaningless. The only reason we know better is the holdout — and a vendor quoting an uplift percentage without describing their holdout is either measuring survivorship or measuring somebody else’s traffic. Ask which. The answer is informative.

What we take from it is a principle rather than a verdict on floors: an optimization lever earns its place by proving itself against a holdout on the traffic it will run on, and a lever that cannot prove it should be turned off rather than defended.

When floors genuinely help

None of the above means floors are useless. Four cases where they clearly earn their keep:

Protecting genuinely premium inventory. When you have inventory a specific set of buyers actively wants — a homepage takeover, a scarce format, a hard-to-reach audience — a floor stops it clearing at commodity prices during a thin auction. Here the floor is doing what floors are for: refusing a bad price on something that has a good one.

Enforcing a commercial agreement. Deal floors on private marketplace and preferred deals are contractual terms, not optimization. They should be set to the agreed number and left alone.

Preventing arbitrage. Without a floor, an intermediary can buy your inventory cheaply and resell it, adding a hop and a fee to a path that is now competing with your own. A floor at a sensible level makes the arbitrage uneconomic.

Refusing the genuinely worthless. Below some price, an impression is not worth the infrastructure to serve and the audience experience to spend. A low absolute floor as a hygiene measure is defensible and costs almost nothing, because there is nearly nothing there.

Notice what these have in common: each is a floor set for a reason you can state other than expected revenue gain. That is the pattern. Floors are excellent at enforcing a policy you have decided on, and unreliable as a revenue optimization lever in their own right.

Key takeaways

  • A floor is a filter, not a negotiation. Below it, buyers do not counter-offer — they disappear.
  • Raising a floor raises average CPM by survivorship, whether or not it worked. Measure revenue per request.
  • First-price auctions plus bid shading mean your floor is an input to the buyer’s pricing model, not a constraint applied to it.
  • Floor results do not transfer between platforms, because the result depends on your inventory’s value distribution. Any vendor’s uplift number is about their traffic, not yours.
  • The expensive failure is invisible: inventory that stops clearing gets deprioritized by buyers, and that does not reverse when you lower the floor.
  • Set from observed clearing prices, segment as finely as volume allows, approach from below, change one thing at a time.
  • Build the off switch first. A lever with no holdout can never be measured.
  • We measured our own adaptive floor lever against a holdout and it came back marginal to negative, so it ships off by default. That is what an honestly measured lever often looks like.
  • Floors are strong at enforcing a policy — premium protection, deal terms, anti-arbitrage, hygiene — and weak as a standalone revenue optimizer.

Floors on Floxis

Floxis is a white-label RTB exchange you run as your own — your domain, your branding, your margin — and floors are treated as a policy instrument you control rather than a black box that promises a number.

Floors are configurable per placement, format and geography, with deal floors honoured as the contractual terms they are. The log-level bid, win and drop ledger that lands in your reporting about a minute after the auction is what makes the measurement in this article possible: revenue per request, bid distributions and drop reasons per demand partner are reports you open, so you can see the impressions a floor refused rather than inferring them from a fill-rate decline. Adaptive floor logic exists, ships off by default, and is measured against a holdout per tenant — because that is the conclusion our own testing supports, and we would rather publish that than an uplift figure we cannot defend.

The wider principle holds across every optimization surface on the platform, and it is worth being explicit about because it cuts against how this category is usually sold. Enrichment makes a request worth more before the auction — that one is mechanical, and it is where the reliable gains are. Statistics decide what to do with the request inside the auction, and every statistical lever is expected to prove itself against a live holdout or be turned off. There is no language model anywhere in that path; a model that takes seconds cannot run inside a 200 ms auction, and any vendor claiming otherwise is describing something that would not work.

If you are evaluating platforms, the floor questions belong on the checklist in our white label ad exchange guide: what granularity can floors be set at, is revenue per request a metric you can see, and can any optimization lever be held out and switched off. Book a demo and we will look at your own clearing distributions.

Sources worth bookmarking