Functional Scope (In-Scope)
- Targeted Ad Matching: Filter eligible ad campaigns based on user context details (geo, device type, audience segments) using the Specification Pattern.
- Second-Price Vickrey Auctions: Run real-time auctions where the winning advertiser pays the second-highest bid plus a $0.01 increment.
- Atomic Budget Deductions: Manage campaign budgets in micro-cents to handle high-concurrency deductions accurately without rounding errors.
- Frequency Capping Guards: Limit identical ad displays to a maximum of N impressions per user per day.
Explicit Boundaries (Out-of-Scope)
- No Complex RTB OpenRTB Bid Protocols: Bypasses live external DSP/SSP bidding round-trips over open web networks.
- No ML-Based Click-Through Rate (CTR) Predictors: Excludes predicting click probabilities using neural networks.
Clean reference designs demonstrating second-price auctions in Java and Python:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.*;
enum DeviceType { MOBILE, DESKTOP, TABLET }
class UserContext {
private final String userId;
private final String geo;
private final DeviceType deviceType;
private final Set<String> interests = new HashSet<>();
public UserContext(String userId, String geo, DeviceType deviceType, List<String> interests) {
this.userId = userId;
this.geo = geo;
this.deviceType = deviceType;
this.interests.addAll(interests);
}
public String getUserId() { return userId; }
public String getGeo() { return geo; }
public DeviceType getDeviceType() { return deviceType; }
public Set<String> getInterests() { return interests; }
}
// Specification Pattern for Targeting Filter
interface TargetingSpecification {
boolean isSatisfiedBy(UserContext context);
}
class GeoTargetingSpecification implements TargetingSpecification {
private final Set<String> allowedGeos;
public GeoTargetingSpecification(String... geos) {
this.allowedGeos = new HashSet<>(Arrays.asList(geos));
}
@Override
public boolean isSatisfiedBy(UserContext context) {
return allowedGeos.isEmpty() || allowedGeos.contains(context.getGeo());
}
}
class DeviceTargetingSpecification implements TargetingSpecification {
private final Set<DeviceType> allowedDevices;
public DeviceTargetingSpecification(DeviceType... devices) {
this.allowedDevices = new HashSet<>(Arrays.asList(devices));
}
@Override
public boolean isSatisfiedBy(UserContext context) {
return allowedDevices.isEmpty() || allowedDevices.contains(context.getDeviceType());
}
}
class AdCampaign {
private final String id;
private final double bidAmount; // in dollars
private final AtomicLong budgetMicroCents;
private final List<TargetingSpecification> targetSpecs = new ArrayList<>();
private final String creativeUrl;
public AdCampaign(String id, double bidAmount, double budget, String creativeUrl) {
this.id = id;
this.bidAmount = bidAmount;
this.budgetMicroCents = new AtomicLong((long)(budget * 1_000_000.0));
this.creativeUrl = creativeUrl;
}
public String getId() { return id; }
public double getBidAmount() { return bidAmount; }
public String getCreativeUrl() { return creativeUrl; }
public void addSpecification(TargetingSpecification spec) {
targetSpecs.add(spec);
}
public boolean matchesTarget(UserContext context) {
for (TargetingSpecification spec : targetSpecs) {
if (!spec.isSatisfiedBy(context)) return false;
}
return true;
}
public boolean tryDeductBudget(double cost) {
long microCost = (long)(cost * 1_000_000.0);
while (true) {
long current = budgetMicroCents.get();
if (current < microCost) return false;
if (budgetMicroCents.compareAndSet(current, current - microCost)) {
return true;
}
}
}
public double getRemainingBudget() {
return budgetMicroCents.get() / 1_000_000.0;
}
}
class FrequencyCapper {
// Map of UserID -> (CampaignID -> ImpressionCount)
private final Map<String, Map<String, Integer>> userImpressions = new ConcurrentHashMap<>();
public boolean isCapReached(String userId, String campaignId, int maxImpressions) {
Map<String, Integer> campaignCounts = userImpressions.get(userId);
if (campaignCounts == null) return false;
return campaignCounts.getOrDefault(campaignId, 0) >= maxImpressions;
}
public void recordImpression(String userId, String campaignId) {
userImpressions.computeIfAbsent(userId, k -> new ConcurrentHashMap<>())
.merge(campaignId, 1, Integer::sum);
}
}
// Strategy Pattern for Auction type
interface AuctionStrategy {
AuctionResult runAuction(List<AdCampaign> campaigns);
}
class AuctionResult {
private final AdCampaign winner;
private final double cost;
public AuctionResult(AdCampaign winner, double cost) {
this.winner = winner;
this.cost = cost;
}
public AdCampaign getWinner() { return winner; }
public double getCost() { return cost; }
}
class SecondPriceVickreyAuction implements AuctionStrategy {
@Override
public AuctionResult runAuction(List<AdCampaign> campaigns) {
if (campaigns.isEmpty()) return null;
if (campaigns.size() == 1) {
// Pay a reserve floor price of $0.01 or custom value
return new AuctionResult(campaigns.get(0), 0.01);
}
// Sort campaign list descending by bid amount
campaigns.sort((a, b) -> Double.compare(b.getBidAmount(), a.getBidAmount()));
AdCampaign winner = campaigns.get(0);
double secondBid = campaigns.get(1).getBidAmount();
double finalCost = secondBid + 0.01; // Vickrey model: Second price + 1 penny
return new AuctionResult(winner, finalCost);
}
}
class AdServingEngine {
private final List<AdCampaign> campaigns = new CopyOnWriteArrayList<>();
private final FrequencyCapper frequencyCapper = new FrequencyCapper();
private final AuctionStrategy auctionStrategy;
private final int dailyCapLimit;
public AdServingEngine(AuctionStrategy auctionStrategy, int dailyCapLimit) {
this.auctionStrategy = auctionStrategy;
this.dailyCapLimit = dailyCapLimit;
}
public void registerCampaign(AdCampaign campaign) {
campaigns.add(campaign);
}
public String serveAd(UserContext context) {
List<AdCampaign> eligibleCampaigns = new ArrayList<>();
for (AdCampaign campaign : campaigns) {
// 1. Evaluate targeting specifications
if (!campaign.matchesTarget(context)) continue;
// 2. Enforce frequency capping guard
if (frequencyCapper.isCapReached(context.getUserId(), campaign.getId(), dailyCapLimit)) {
System.out.println("Frequency limit reached for Campaign " + campaign.getId() + " and User " + context.getUserId());
continue;
}
// 3. Verify budget exists
if (campaign.getRemainingBudget() <= 0.0) continue;
eligibleCampaigns.add(campaign);
}
if (eligibleCampaigns.isEmpty()) {
return "creative_fallback.jpg"; // Default fallback creative
}
// 4. Run second-price Vickrey auction
AuctionResult result = auctionStrategy.runAuction(eligibleCampaigns);
if (result == null) return "creative_fallback.jpg";
AdCampaign winner = result.getWinner();
double cost = result.getCost();
// 5. Try atomic budget deduction
if (winner.tryDeductBudget(cost)) {
frequencyCapper.recordImpression(context.getUserId(), winner.getId());
System.out.println("Served Ad: " + winner.getId() + " to " + context.getUserId()
+ ". Winner bid: $" + winner.getBidAmount() + ". Final Price Paid: $" + String.format("%.2f", cost));
return winner.getCreativeUrl();
} else {
// Recurse / fallback if winner ran out of budget in a race condition
System.out.println("Winner " + winner.getId() + " failed budget check due to concurrent checkout. Retrying...");
return serveAd(context);
}
}
}
// Complete Simulation
public class Main {
public static void main(String[] args) {
AdServingEngine engine = new AdServingEngine(new SecondPriceVickreyAuction(), 2);
// Define campaigns with different bid sizes
AdCampaign c1 = new AdCampaign("C-NIKE", 2.50, 10.00, "nike_shoes.jpg");
c1.addSpecification(new GeoTargetingSpecification("US", "CA"));
c1.addSpecification(new DeviceTargetingSpecification(DeviceType.MOBILE));
AdCampaign c2 = new AdCampaign("C-ADIDAS", 1.80, 15.00, "adidas_boost.jpg");
c2.addSpecification(new GeoTargetingSpecification("US"));
AdCampaign c3 = new AdCampaign("C-PUMA", 3.00, 0.50, "puma_wild.jpg"); // puma high bid but very low budget
c3.addSpecification(new GeoTargetingSpecification("US"));
engine.registerCampaign(c1);
engine.registerCampaign(c2);
engine.registerCampaign(c3);
UserContext user = new UserContext("U-Mark", "US", DeviceType.MOBILE, Arrays.asList("sports", "running"));
// 1. Serving first ad - expect Puma to win but pay second price ($2.51)
System.out.println("--- Ad Request 1 ---");
engine.serveAd(user);
// 2. Puma budget is now $0.50 - $2.51 = failed (insufficient budget)
// Next request - expect Nike to win and pay Adidas's price ($1.81)
System.out.println("\n--- Ad Request 2 ---");
engine.serveAd(user);
// 3. Nike wins again, pays Adidas ($1.81)
System.out.println("\n--- Ad Request 3 ---");
engine.serveAd(user);
// 4. Frequency cap check (Nike has been shown 2 times, limit is 2)
// Nike should be blocked. Expect Adidas to win and pay reserve limit ($0.01)
System.out.println("\n--- Ad Request 4 (Capping verification) ---");
engine.serveAd(user);
}
}