What Is Real-Time Bidding?
Real-Time Bidding (RTB) is the programmatic auction mechanism behind most digital display advertising. When a user visits a webpage, an ad impression opportunity is auctioned in under 100 milliseconds via OpenRTB protocol. Advertisers’ Demand-Side Platforms (DSPs) submit bids; the publisher’s Supply-Side Platform (SSP) picks the winner; the winning ad is served in the response. At Google/Meta scale: 10 million auctions per second.
Auction Flow (end to end, sub-100ms)
- User loads page. Publisher’s ad tag fires bid request to SSP.
- SSP broadcasts bid request to N DSPs in parallel (30ms timeout).
- Each DSP: user lookup in Redis (<1ms) → targeting evaluation → ML bid price prediction → submit bid.
- SSP collects bids, runs second-price auction (winner pays second-highest bid + $0.01).
- Winning DSP receives win notice, serves creative from CDN.
- SSP sends loss notices to all other DSPs (budget not charged).
DSP Architecture
User Profile Store
User targeting data (demographics, interest segments, behavioral history) must be retrieved in under 1ms. Store in Redis as a compact binary blob (protobuf) keyed by user_id or cookie_id. Shard by user_id hash. Use local in-process L1 cache (LRU, 100K most active users) in front of Redis to handle hot users without network RTT.
Targeting Engine
For each bid request, evaluate targeting criteria: geo (country/DMA), device type, browser, audience segment, domain whitelist/blacklist, time of day, frequency caps. Compiled into a decision tree or bitset intersection. Must run in under 5ms for the entire targeting pass across all active line items (campaigns).
Bid Price Prediction
ML model (gradient boosted trees or DNN) predicts the probability of a click or conversion given user + ad + context features. Bid price = predicted_value * budget_efficiency_factor. Models are trained offline on historical win/click/conversion data and updated daily. Served via low-latency feature retrieval + model inference in 10-20ms.
Frequency Capping
Limit how many times a user sees the same ad (e.g., max 5 impressions per day per campaign). Implementation: Redis sorted set per user per campaign: ZADD user:{uid}:cap:{campaign_id} {timestamp} {impression_id}. Before bidding: ZCOUNT user:{uid}:cap:{campaign_id} {day_start} {now} — if count >= 5, skip this campaign. ZREMRANGEBYSCORE to purge old entries during cleanup. The key challenge: across millions of users, this is billions of Redis keys. Use Redis Cluster with 128+ shards, or use approximate counting (HyperLogLog is too approximate for strict caps — use exact sorted set).
Budget Pacing
Advertisers set daily budgets (e.g., $10,000/day). Without pacing, a budget exhausts in the first hour of the day. Goal: spread spend evenly across 24 hours (or by traffic curves). Implementation: compute target_spend_so_far = (current_hour / 24) * daily_budget. If actual_spend < target: boost bid prices to win more. If actual_spend > target: throttle by randomly skipping bid requests. Use a token bucket or leaky bucket at the campaign level. Throttle decisions happen in microseconds — done locally in the DSP before sending bids.
Win Rate Optimization (Bid Shading)
In second-price auctions: bidding your true value is theoretically optimal. In first-price auctions (common in header bidding): overbidding wastes spend, underbidding loses impressions. Bid shading: predict the clearing price distribution for this impression and bid slightly above the expected second price. Trained on historical clearing prices for similar (domain, geo, audience) auctions. Reduces CPM by 15-20% vs. naive bidding.
Interview Tips
- 100ms SLA is non-negotiable — every component (user lookup, targeting, ML inference) must be profiled against this budget.
- Second-price vs. first-price auction mechanics are frequently asked — know when each is used.
- Frequency capping and budget pacing are “senior” details that differentiate responses.
- Win/loss signals are critical for ML model training — explain how you close the feedback loop.
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “How does a second-price auction work and why is it used in RTB?”,
“acceptedAnswer”: { “@type”: “Answer”, “text”: “In a second-price (Vickrey) auction, the highest bidder wins but pays the second-highest bid plus a small increment (e.g., $0.01). This is used in RTB because it incentivizes truthful bidding: the optimal strategy is to bid your true value regardless of what others bid. Proof: if you bid above your value and win, you might pay more than the impression is worth. If you bid below your value, you might lose an impression you should have won. Bidding your true value maximizes expected value in all cases. First-price auctions (increasingly common in header bidding) require bid shading — bidding below true value to avoid overpaying. Second-price is simpler for DSPs, but first-price has become dominant because SSPs earn more revenue and it is simpler to implement without the sealed-bid guarantee.” }
},
{
“@type”: “Question”,
“name”: “How do you implement frequency capping at scale in an RTB system?”,
“acceptedAnswer”: { “@type”: “Answer”, “text”: “Frequency capping (max impressions per user per campaign per time window) must be enforced in under 1ms per bid request. Implementation: Redis sorted set per (user, campaign): key = freq:{user_id}:{campaign_id}, score = unix timestamp, value = impression_id. Before bidding: ZCOUNT key {window_start} {now} — if count >= cap, skip. After winning: ZADD key {now} {impression_id}. Use ZREMRANGEBYSCORE periodically to clean old entries. Scaling challenges: 100M daily active users * 1000 campaigns each = 100B potential keys. Use Redis Cluster (128 shards). For campaigns with very high caps or long windows, use Redis HyperLogLog for approximate counts (saves 90% memory, 0.81% error — acceptable for soft caps). Exact sorted set for hard financial caps. TTL on keys = window duration to auto-expire inactive users.” }
},
{
“@type”: “Question”,
“name”: “What is bid shading and when is it applied?”,
“acceptedAnswer”: { “@type”: “Answer”, “text”: “Bid shading reduces the bid price below true value to avoid overpaying in first-price auctions. In second-price auctions, truthful bidding is optimal. In first-price auctions (now dominant in header bidding), you pay what you bid — bidding true value means paying the full amount even if the second bidder was far below. Bid shading: predict the clearing price distribution for this specific impression (domain + geo + audience + time) using a statistical model trained on historical win data. Bid at the predicted 50th-75th percentile of the clearing price distribution — likely to win but not overpay. Implementation: the bid shading model takes impression features and outputs a shading factor (0.7 = shade 30%). Effective bid = true_value * shading_factor. DSPs that implement bid shading reduce CPM by 15-20% vs. naive first-price bidding while maintaining similar win rates.” }
}
]
}