# System Design: Ad Server — Targeting, Real-Time Bidding, Impression Tracking, and Click Attribution

Source: https://www.techinterview.org/post/3233465493/system-design-ad-server/
Updated: 2026-04-17 · techinterview.org

## Overview

An ad server matches advertisers' ads to available ad slots on publisher pages in real time. The two main models: direct (publisher sells inventory directly to advertisers at a fixed CPM) and programmatic (real-time bidding, RTB: advertisers bid for each impression in an auction lasting ~100ms). Google Display Network, Facebook Ads, and The Trade Desk use RTB. The components: a Supply-Side Platform (SSP, publisher-side), a Demand-Side Platform (DSP, advertiser-side), and an Ad Exchange that runs the auction between them.

## Ad Request Flow (RTB)

User loads a page containing an ad slot. The publisher's ad tag fires: it sends an ad request to the SSP with bid_request: {impression_id, publisher_id, page_url, ad_slot_size, user_id (cookie or device ID), geolocation, user_agent, floor_price}. The SSP fans out the bid request to multiple DSPs simultaneously (100ms deadline). Each DSP evaluates: does this user match any advertiser's targeting criteria? What is the maximum bid for this impression? Returns bid_response: {bid_price, ad_markup}. The SSP runs a second-price auction (winner pays second-highest bid + $0.01). The winning ad markup is returned to the browser, which renders the ad. Total latency budget: 100ms end-to-end.

## Targeting

Advertisers define targeting criteria: demographic (age, gender), geographic (country, city, zip), behavioral (retargeting users who visited the advertiser's site), contextual (page content matches keywords), device (mobile, desktop), time of day, browser/OS. User matching: each user has a profile built from cookie data (browsing history, inferred interests, demographics). Stored in a user data platform (DMP): user_id → {segments: [sports_fan, tech_enthusiast], age_bracket: 25-34, location: NYC}. At bid time: the DSP loads the user profile from Redis (sub-millisecond lookup) and evaluates each active campaign's targeting rules against the profile. Only matching campaigns generate bids.

## Budget Pacing

Advertisers set daily budgets. If all impressions are served in the morning, the budget is exhausted and no ads run in the afternoon. Pacing: spread spend evenly across the day. Two approaches: throttling (set a probability P of bidding for each impression; adjust P to hit the target hourly spend rate), and target CPM bidding (the DSP dynamically adjusts bid prices down when ahead of pace, up when behind). Implementation: a pacing service runs every 5 minutes, computes each campaign's ideal spend so far (budget * elapsed_fraction_of_day), compares to actual spend, and adjusts the bid multiplier. Store budget state in Redis: spend:{campaign_id}:{date} incremented on each win. Atomic INCR prevents race conditions.

## Impression and Click Tracking

Impression tracking: when an ad is rendered, the browser fires a pixel (1x1 image) to the impression tracking URL: GET /impression?imp_id=XYZ&creative_id=ABC. The tracking server logs: {impression_id, campaign_id, creative_id, publisher_id, user_id, timestamp, bid_price}. Click tracking: the ad's destination URL is wrapped: GET /click?imp_id=XYZ&url=https://advertiser.com. The click server logs the click, updates click count, and 302-redirects to the final URL. The redirect adds ~50ms but enables click attribution. Duplicate detection: SETNX imp_id in Redis with TTL=1 hour to deduplicate pixel fires from the same impression (browsers can fire pixels multiple times on slow connections).

## Attribution

Attribution answers: which ad caused a conversion (purchase, signup)? Last-click attribution: credit the last ad clicked before the conversion. Multi-touch: distribute credit across all ads in the conversion path. Implementation: on conversion, the advertiser's site fires a conversion pixel with the same user cookie. The attribution server looks up the user's click history (last 30 days, stored in a clickstream table) and associates the conversion with the matching campaign. Report conversion counts back to the DSP for optimization. Privacy: third-party cookies are being deprecated. Modern attribution uses privacy-preserving APIs (Chrome's Attribution Reporting API) and server-to-server postbacks using hashed email or phone as the match key.

## Interview Tips

- Frequency capping: limit impressions per user per campaign per day. Track in Redis: INCR freq:{campaign_id}:{user_id}:{date} with EX 86400. If count > cap, skip the campaign for this user.

- Second-price auction: winner pays second-highest bid. Incentivizes truthful bidding (DSPs bid their true valuation). Vickrey auction theory.

- Cold start for new users: no behavioral profile. Use contextual targeting (page content) or lookalike modeling (match to similar known users).

Asked at: [Meta Interview Guide](https://techinterview.org/meta-interview/)

Asked at: [Twitter/X Interview Guide](https://techinterview.org/twitter-interview/)

Asked at: [Snap Interview Guide](https://techinterview.org/snap-interview/)

Asked at: [LinkedIn Interview Guide](https://techinterview.org/linkedin-interview/)
