java-bidder

Plain Java 21 · real-time ad bidding · no frameworks

A 20 ms ad auction, live.

An exchange offers an ad slot; the bidder has 20 ms to match campaigns, check pacing, frequency caps and budget, score, shade a first-price bid, and answer. Every dot below is one auction going through that pipeline.

Connecting… Source on GitHub →
Idle

This page plays the exchange: a steady stream of random bid requests (or bursts of 1,000 or 10,000, 50 in flight), a win notice for about 40% of bids, and about 5% of win notices sent twice to prove the bidder never charges twice.

Live auction flow

Each dot is one bid request moving through Bidder.decide(). It falls out at the gate that said no; bids that win turn green when the exchange's win notice arrives.

Round-trip latency

Per request, as this page (the exchange) sees it; log scale, square-root heights so rare slow requests stay visible. Browsers round timers to about 0.1 ms. The red line is the 20 ms deadline.

Throughput

Requests answered per second, last 60 seconds

Where requests go

Each stage of Bidder.decide(), and how many requests it drops

Live auctions

Most recent first

Send requests to see auctions here.

Campaign budgets

Spend against budget. Pacing lowers the throttle when a campaign spends ahead of its daily line (a "day" is 5 minutes here).

Won spend Reserved by open bids Remaining budget
CampaignSpendBudgetLeasedThrottle

How it fits together

Solid arrows are the hot path inside one bid. Dotted arrows are background jobs that only publish values the hot path reads.

Bidder.decide() · hard 20 ms deadline any stage can end it: NoBid(reason) Background · ScheduledExecutorService Ad exchange this page HttpServer virtual thread / request 1 · Match CampaignIndex 2 · Pace Pacer.throttle 3 · Freq cap FrequencyCap 4 · Score + shade Pricing 5 · Reserve BudgetSlices CAS BudgetService central budget POST /bid lease slice Index refresh every 30 s swap snapshot Pacer.step every 1 s throttle expireLosses every 1 s release lost bids Bidder.win() exactly once per auction POST /win count impression refund bid − clearing

Where each piece lives in the Java

Plain JDK 21, no frameworks. Read in this order. New to modern Java? Java since 2015, for Python developers →