Winnow

Ad & content targeting

On this page

Online advertising is the textbook "many rules, one event, tiny deadline" problem; it's the use case Winnow's design fits most directly.

⚡ Where speed pays for itself

On the bidding path, a decision that misses the ~100 ms window is not a slow bid; it is no bid, and that revenue is gone. Evaluating one impression against millions of rules in microseconds lets you bid on inventory a slower engine would forfeit, at millions of requests per second on a fraction of the hardware. Latency here is revenue: Amazon measured every +100 ms at roughly −1% of sales, so retrieval speed is the margin, not a nice-to-have.

The stakes🔗

When a page loads, an auction decides which ad to show, and it has almost no time. The real-time bidding round trip completes in under 100 milliseconds; the industry OpenRTB bid-response window is about 100 ms, and a bid that arrives late is simply dropped. Exchanges field millions of bid requests per second (AWS). Latency is money: Amazon famously found every 100 ms of added latency cost ~1% of sales. If your targeting decision is slow, you don't bid, and you don't earn.

The prize is large and growing fast. The real-time-bidding market was about $28 billion in 2025 and is projected to grow on the order of 33% a year, to ~$276 billion by 2033 (Market Data Forecast), carrying well over half a trillion dollars of annual programmatic ad spend (Statista).

How it works: the reverse query (a "percolator")🔗

Most queries match one rule against many records. Targeting inverts it: a single impression (the event: this user, this app, this moment) is matched against millions of campaign rules, each describing the audience and context a campaign wants. The engine returns the campaigns whose rules the impression satisfies; those enter the auction. A campaign's targeting rule might say "bid when the app is 91, the country is the US (id 1) or unspecified (0), the user is 18–34, and the OS is at least version 14." The incoming impression's attributes are tested against every campaign's rule at once.

🤖 With AI in the loop

In every major ad platform, rules run before the AI. Snap makes trillions of ranking predictions a day, but the first stage of its funnel is pure rules: targeting, budget, privacy, and policy checks decide which of millions of ads are even eligible before any model scores a candidate. Meta admits only ads whose targeting includes the person into the auction; at Pinterest, the whole funnel (billions of items down to 1,000–2,000 ranking candidates) must fit a 200–300 ms budget. That front gate is exactly Winnow's job: prune millions of campaign rules to a shortlist in microseconds, so the expensive ranking model only ever sees ads that could actually serve. More patterns: Deep Dive: AI + Rules Engines.

The bidding budget🔗

The window is the whole argument. A bid response is due in about 100 milliseconds from the exchange's request to your bytes arriving back, and a response that misses it is not ranked lower — it is dropped. Out of that budget the network takes what it takes, the bidder decodes the request, the targeting match produces a shortlist, and the ranking model prices what survives. Only one of those steps is Winnow's.

So the question is not whether the match is fast in the abstract. It is what fraction of the window that one step spends, and what a slower one would have spent instead.

A 100 ms bid-response window, and the slice a 2,000,000-rule match takes

THE 100 MS WINDOW · TO SCALE Winnow · rule index 2,000,000 campaign rules Traditional DB · no index the same rule book ~1 µs · 0.001% of the window ~42 ms · 42% of the window 0 20 ms 40 ms 60 ms 80 ms 100 ms THE FIRST 20 µs OF THAT BAR, MAGNIFIED 5,000× Winnow · rule index 2,000,000 campaign rules Traditional DB · indexed key its best case, same book ~1 µs ~13 µs · 13× the time 0 5 µs 10 µs 15 µs 20 µs Neither bar in this zoom is visible in the window above — which is the point: the match is not where the 100 ms goes.

The green hairline is the entire targeting decision. Against 2,000,000 standing rules it is one hundred-thousandth of the window, so essentially the whole budget is left for the network hop and the ranking model that actually need it. The amber bar is the same rule book on a database with no usable index, from the same benchmark run: 42 ms is not a slow match, it is 42% of the bid budget spent before the auction has a single candidate. Per-event times are measured at 2M rules in Deep Dive: Cost Savings; the ~100 ms window is the industry's number, not ours.

Why Winnow fits🔗

  • Measured at this scale. In Deep Dive: Cost Savings, Winnow matches an event against 2,000,000 standing rules in ~1 microsecond — ten times the rule book for 1.4× the time; that's the exact shape described above, with effectively the whole window still to spare.
  • The whole rulebook in one pass. Rules are checked together, not one by one, and the engine starts with the condition that eliminates the most, so most campaigns are ruled out having barely been looked at.
  • Headroom in the budget. Microsecond matching leaves essentially the whole ~100 ms window for the rest of the bid pipeline, instead of spending it on the match.
  • Runs inside your bidder. The matcher is a library embedded in your own bidding software. No call to a separate rules service sits on the hot path.