Built on Oliver · Demand‑side platforms

Every impression. Not a sample.

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.

OpenRTB 2.6 every request kept pricing in one pass
The shape of the day

A billion decisions, and a handful of outcomes.

Every stage down the funnel throws away almost everything above it. The rows you need to explain a loss are the ones nobody kept.

Illustrative shape, not a customer’s numbers — the ratios are what the industry publishes about itself.
Where we sit

Not in the bid. In the loop that feeds it.

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.

the bidder’s clock — fixedtmax ≈ 100 ms
bid request bidder reads state in memory bid
no database in this path — ours or anyone’s
the loop’s clock — yours to sethourly
OliverDB
this is the clock that used to be nightly
Feeding the bidder · one example

Price every cell, in one read.

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.

one query, every pricing cell
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
the surface
cheapexpensive · every cell priced together
Percentiles come from sketches the engine already keeps, so the distribution is read rather than recomputed. Batch execution
End to end

Four families of question, one store.

From the payload landing to the decision it eventually changes — every stage asks something different of the data underneath it.

01

On the way in

OpenRTB payloads flattened to rows, with the deep optional branches kept rather than dropped.

  • Nested imp, device, geo and user objects shaped at ingest
  • ext fields an exchange shipped last week, queryable as attributes — no migration
02

Stitching the funnel

The join nobody advertises. Request, bid, win notice, impression, click and conversion arrive at different times, from different systems, on different keys.

  • One coherent row per opportunity, assembled from five arrival streams
  • Late conversions attached to auctions that closed days earlier
03

Feeding the bidder

Everything the hot path reads out of memory has to be computed somewhere. This is that somewhere.

  • Clearing‑price percentiles for every pricing cell
  • Win rate as a function of bid price — the curve, not just the number
  • Segment membership and sizes across hundreds of definitions
  • Pacing: spend per campaign per minute against its cap
  • Frequency: how often this person already saw this creative
  • Blocklists and brand‑safety domain sets
04

Answering humans

The questions that arrive without warning and cannot be precomputed, because nobody knew to ask them yesterday.

  • Why did we lose that impression
  • Supply‑path optimisation — the same impression offered four ways, and which path is actually cheapest
  • Discrepancy reconciliation: our counts against theirs
Where we fit

What lands on Oliver, and what comes back.

The record

Every bid request and response, win notice, impression, click and conversion — kept whole rather than sampled down to what fitted.

  • OpenRTB payloads with their ext branches intact
  • Losses as well as wins — the half most desks discard
  • Conversions attached to auctions that closed days earlier
What gets rebuilt from it

Everything the bidder reads out of memory has to be computed somewhere, on a clock you choose.

  • Clearing‑price surfaces and win curves
  • Segment membership and sizes
  • Pacing counters, per campaign, per minute
  • Frequency counts and brand‑safety sets
What you can suddenly ask

The questions that arrive without warning, which only have answers if the rows are still there.

  • Why that auction was lost
  • Which supply path is actually the cheapest
  • Where your counts and theirs diverge
And the one nobody else can answer

What if you had bid differently yesterday?

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.

what happened
what would have happenednew floor & curve
A desk that samples cannot run this at all — only extrapolate from the part it kept.

Stop pricing today’s bids off yesterday’s market.