Design an ad serving system that selects and delivers the most relevant ad for each impression within a strict latency budget. The system must manage campaign budgets, pacing, targeting, and attribution at scale. A teaching design inspired by real ad servers, not any one company's internal architecture.
Understand basic ad auction: request targeting, campaign filtering, and simple first-price auction.
What was missing: Nothing yet: one ad server picks an ad for every request.
Why that's risky: Every ad request (100K per second) hits the campaigns database, which handles only half that, and one server is also at its limit.
What gets added: An ad server that filters campaigns by targeting, ranks them by bid and returns the winner, reading campaigns from the database on every request.
Trade-offs: Simplest auction possible, but the database sits on the critical path of every page view.
Cache campaign metadata and targeting indices; horizontally scale ad servers.
What was missing: Campaign data was read from the database on every request, and there was only one ad server.
Why that's risky: Each ad server enforces budgets on its own, so together they overspend a campaign.
What gets added: A campaign cache holding targeting rules and bids in memory (about 95% hit rate), and a load balancer spreading requests over two ad servers.
Trade-offs: Cached campaign data can be a little stale; edits take effect when the cache refreshes.
Stop showing a campaign's ads once its budget is spent, even with many ad servers running at once.
What was missing: Budgets were checked separately on each server, so campaigns overspent.
Why that's risky: Impressions and clicks are logged synchronously, adding database writes to every ad request.
What gets added: A shared budget tracker (Redis) that counts each campaign's spend with atomic increments; ad servers skip campaigns that are out of budget, and totals are saved to the database periodically.
Trade-offs: Spend counts are pushed to the database in batches, so a crash can lose a few seconds of counting; the overspend this allows is tiny.
Decouple impression logging from ad serving using queues.
What was missing: Logging each impression and click happened inside the ad request.
Why that's risky: Bots and click farms are billed as real traffic.
What gets added: An ad view & click queue and a stats & billing worker that aggregates events, records spend and writes reporting stats off the request path.
Trade-offs: Reports lag by seconds to minutes, in exchange for ad requests that never wait on logging.
Detect invalid traffic patterns and protect revenue.
What was missing: Nothing distinguished invalid traffic from real people.
Why that's risky: Everything runs in one zone: a zone outage stops all ads.
What gets added: A click fraud detector reading the same event queue in parallel, flagging bot patterns (rapid clicks, impossible click-through rates, spoofed devices) so they are excluded from billing.
Trade-offs: Detection runs after the fact, so flagged clicks are removed from bills rather than blocked in real time.
Deploy across availability zones for high availability and resilience.
What was missing: A single zone, ranking inside the ad servers, no protection against request floods, and ad images served by the ad servers.
Why that's risky: Remaining risk is cross-region: a full region outage would need a second region.
What gets added: Two availability zones each with their own load balancer, ad servers, ranking service, campaign cache and budget tracker; a global load balancer and rate limiter in front; a replicated event pipeline; and a CDN for ad images and videos.
Trade-offs: Running two full zones doubles idle capacity, which is the price of surviving a zone failure.
You're in the middle of an interview session. Leaving now will end your current attempt.
Explore concept overviews, real-system examples, key tradeoffs, and interview talking points for each roadmap section.
You've conquered this phase. These are the skills you now own: