Jiangang Han

A Primer on Ad Bidding

Three short posts, written from the seat of an advertiser's bidding agent, that lay out the basic math of "how much should I bid?" in ad auctions: from a single auction, to a day of auctions sharing one budget, to pacing that budget in real time.

Each post is built around one core formula, with derivations, figures, and notes on how to read the formula in business terms and what goes wrong in production. The posts build on each other, but each one stands on its own. If you just want the big picture, the two sections below — "Three words to tell apart" and "What the three posts cover" — are all you need.


Three words to tell apart: pricing, bidding, pacing

In one sentence: pricing is the seller setting the rules, bidding is the buyer deciding how much to offer each time, and pacing is the buyer controlling how fast the money goes.

An analogy. An auction house is selling 1,000 lots today, and you walk in with a budget of 100,000:

In online advertising, all three happen every day:

Who does itHow oftenWhat it looks like in adsCovered in
PricingThe platformThe rules rarely change; reserve prices can adjust dynamicallyFirst-price, second-price, GSP; reserve prices; charging per impression, click or conversionPart 1
BiddingThe advertiser, or an autobidder acting for themOnce per impression, in millisecondsManual bids, or automated strategies such as "maximize conversions" and "target CPA"Parts 1 & 2
PacingSame as aboveEvery few minutesThrottling, or scaling all bids up or downPart 3

One formula ties the three together: bid b = \alpha \times v.

How a bid gets made

Show: a few terms that often get mixed up

What the three posts cover

1 · Bidding in a Single Auction 8 min

The question: with just one auction, how much should you bid? And does it matter whether the platform runs a first-price or a second-price auction?

To a bidder, the market is just one random number: the highest bid among everyone else. From it we get the win-rate curve and the cost curve, and see why you bid your true value under second price but shade your bid under first price. Finally, we take the platform's side for a moment: setting the reserve price turns out to be exactly the problem from Part 1 of the pricing series.

Takeaway: under second price, the marginal cost of one more win is exactly your bid. Everything in the next two posts grows out of this one fact.

2 · Bidding Under a Budget 10 min

The question: thousands of auctions a day share one budget — how much should you bid in each?

Add the budget constraint. Once the Lagrangian splits apart, every auction turns back into Part 1's problem, except that each value is divided by the same number \lambda — the \alpha = 1/\lambda in the formula above.

Takeaways: b = v/\lambda; equal values mean equal bids, however strong or weak the competition; and the precise version of "doubling the budget doesn't double the results".

3 · Budget Pacing 10 min

The question: the optimal \lambda can't be computed in advance — so how do you adjust it while the campaign runs?

Why lowering bids beats throttling, when the update rule converges and when it oscillates, how to recover from a bad start, and what happens when cost caps come in or when every advertiser is adjusting at once.

Takeaways: an update rule that fits in a few lines of code, and a single product, \eta e, that tells you whether it will oscillate.


How this relates to the pricing series

The pricing series takes the seller's side: facing a demand curve q(p) that falls as the price rises, decide what to charge. This series takes the buyer's side: facing a win-rate curve w(b) that rises with the bid, decide what to offer. The two frameworks line up almost one to one:

Pricing (seller)Bidding (buyer)
The curve you faceDemand q(p), decreasingWin rate w(b), increasing
Optimum for a single decisionp^\star = c + q/(-q'): mark up from costFirst-price b^\star = v - w/w': shade down from value
Knob created by a coupling constraintShadow price \lambdaShadow price \lambda, bid multiplier 1/\lambda
What the optimum looks likeMarginal unit economics leveledMarginal ROI leveled

Notation

Shared by all three posts. Each post also opens with a collapsible table of the symbols it uses.

SymbolMeaningIn your business, this might be
bBid, the decision variable, always converted to a per-impression amountCPC bid × pCTR
zMarket price: the highest bid among everyone elseThe highest competing eCPM in auction logs
w(b)Win-rate curve, P(z \le b)Bid landscape, win-rate model
c(b)Expected spend per opportunity; c_1 first price, c_2 second priceExpected cost per ad request
vWhat an impression opportunity is worth to youpCVR, or pCTR × value per click
rReserve priceReserve price, floor price
B,\ TTotal budget; number of auctions (opportunities)Daily budget; daily request volume
\lambdaMultiplier of the budget constraint, the shadow priceHow many more conversions one more dollar of budget buys
\alpha = 1/\lambdaBid multiplierPacing multiplier
R_kActual ÷ planned spend in time window kIntraday spend progress
\eta,\ eUpdate step size; elasticity of spend with respect to the bidController gain; % change in spend per 1% change in bid
C,\ \muCost cap and its multiplierTarget CPA

Formula cheat sheet

SettingResult
Win ratew(b) = P(z \le b)
Expected spendFirst price c_1 = b\,w(b); second price c_2 = \int_0^b z\,w'(z)\,dz
Cost of one more winSecond price b; first price b + w/w'
Optimal bid in a single auctionSecond price b^\star = v; first price b^\star = v - w/w'
Reserve price (one bidder)r^\star = \bigl(1 - F(r^\star)\bigr)/f(r^\star)
Under a budget, second priceb_t^\star = v_t/\lambda, with \lambda^\star satisfying \sum_t c_t(v_t/\lambda^\star) = B
Under a budget, first priceb_t^\star = v_t/\lambda - w_t/w_t'
Shadow price of the budgetdV^\star/dB = \lambda^\star
Uniform market price on [0, m], equal valuesb^\star = \sqrt{2mB/T}, N^\star = \sqrt{2TB/m}, marginal CPA = 2 × average CPA
Throttling vs. lowering bidsN(pS_0) \ge p\,N(S_0)
Online update\alpha \leftarrow \alpha\,e^{-\eta(R_k - 1)}, log error x_{k+1} \approx (1 - \eta e)\,x_k
Budget + cost capb = \dfrac{1 + \mu C}{\lambda + \mu}\,v

What this series doesn't cover

All three posts assume you already have calibrated value predictions v and a reliable win-rate curve w(b), and ask how to bid once you have them.

Getting those two is actually the hardest, most "statistical" part of any bidding system (censored data, selection bias, non-stationarity). That, along with multi-slot GSP, mechanism design on the platform side, and multi-day budget planning, is listed in the last section of Part 3.


References

  1. Yuan Gao, Kaiyu Yang, Yuanlong Chen, Min Liu, Noureddine El Karoui. Bidding Agent Design in the LinkedIn Ad Marketplace. AdKDD 2022.
  2. Weinan Zhang, Shuai Yuan, Jun Wang. Optimal Real-Time Bidding for Display Advertising. KDD 2014.
  3. Weinan Zhang, Kan Ren, Jun Wang. Optimal Real-Time Bidding Frameworks Discussion. arXiv:1602.01007, 2016.
  4. Jon Feldman, S. Muthukrishnan, Martin Pál, Cliff Stein. Budget Optimization in Search-Based Advertising Auctions. EC 2007.
  5. Deepak Agarwal, Souvik Ghosh, Kai Wei, Siyu You. Budget Pacing for Targeted Online Advertisements at LinkedIn. KDD 2014.
  6. Santiago Balseiro, Yonatan Gur. Learning in Repeated Auctions with Budgets: Regret Minimization and Equilibrium. Management Science, 2019.
  7. Roger Myerson. Optimal Auction Design. Mathematics of Operations Research, 1981.
  8. Benjamin Edelman, Michael Ostrovsky, Michael Schwarz. Internet Advertising and the Generalized Second-Price Auction. American Economic Review, 2007.
  9. Wush Chi-Hsuan Wu, Mi-Yen Yeh, Ming-Syan Chen. Predicting Winning Price in Real Time Bidding with Censored Data. KDD 2015.
  10. Vincent Conitzer, Christian Kroer, Eric Sodomka, Nicolás Stier-Moses. Multiplicative Pacing Equilibria in Auction Markets. Operations Research, 2022.
  11. Min Liu, Jialiang Mao, Kang Kang. Trustworthy and Powerful Online Marketplace Experimentation with Budget-split Design. KDD 2021.
  12. Gagan Aggarwal et al. Auto-bidding and Auctions in Online Advertising: A Survey. ACM SIGecom Exchanges, 2024.

Every figure in this series is computed directly from the models in the text; none of them are sketches. Every derivation has been checked numerically (finite differences for derivatives, brute-force search for optima, Monte Carlo for expectations). If you spot a mistake, please let me know.