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.