On the way in
OpenRTB payloads flattened to rows, with the deep optional branches kept rather than dropped.
- Nested
imp,device,geoanduserobjects shaped at ingest extfields an exchange shipped last week, queryable as attributes — no migration
A bidder sees tens of thousands of requests a second and throttles, skips and samples to survive it — then prices tomorrow’s bids off whatever survived. Oliver keeps all of it, and answers the questions a bidder actually needs fast enough to act on.
Every stage down the funnel throws away almost everything above it. The rows you need to explain a loss are the ones nobody kept.
A bidder answers inside the exchange’s tmax — around a hundred milliseconds including the network, and single digits for its own decision. Nothing queries a database in that window, and Oliver does not pretend to. It runs the other clock: everything that happened lands here, and the state the bidder reads is rebuilt from it.
A shading model needs a clearing‑price distribution and a win curve for every exchange, publisher, format, device and geography it might bid into. That is a cross‑product of tens of thousands of cells — which is why most desks rebuild it overnight, and bid all day against yesterday’s market.
SELECT exchange, publisher_id, ad_format,
device_type, geo_country,
count(*) AS bids,
avg(won) AS win_rate,
percentile_cont(0.25) WITHIN GROUP
(ORDER BY clear_price) AS p25,
percentile_cont(0.50) WITHIN GROUP
(ORDER BY clear_price) AS p50
FROM auctions
WHERE ts >= now() - INTERVAL '7 days'
GROUP BY 1, 2, 3, 4, 5
From the payload landing to the decision it eventually changes — every stage asks something different of the data underneath it.
OpenRTB payloads flattened to rows, with the deep optional branches kept rather than dropped.
imp, device, geo and user objects shaped at ingestext fields an exchange shipped last week, queryable as attributes — no migrationThe join nobody advertises. Request, bid, win notice, impression, click and conversion arrive at different times, from different systems, on different keys.
Everything the hot path reads out of memory has to be computed somewhere. This is that somewhere.
The questions that arrive without warning and cannot be precomputed, because nobody knew to ask them yesterday.
Every bid request and response, win notice, impression, click and conversion — kept whole rather than sampled down to what fitted.
ext branches intactEverything the bidder reads out of memory has to be computed somewhere, on a clock you choose.
The questions that arrive without warning, which only have answers if the rows are still there.
One configuration, re‑decided against every request you kept. Not a sample, not a model of your inventory — the actual inventory, run again. It is the same shape as everything else on this page: one pass, every question at once.