Deep Dive: Cost Savings
On this page
A rule engine's job is to take one event and check it against a book of standing rules: does this transaction match any fraud pattern? which offers does this customer qualify for? is this request allowed? The honest question for a buyer is simple: how fast, at what cost, compared with the alternatives you'd actually reach for? And does it stay that way as the rule book and the traffic grow?
So we built the comparison on exactly that shape: a book of 200,000 standing rules, the same rules, the same events, the same machine, testing Winnow against a hand-written program, a traditional database (SQLite), and a modern analytics database (DuckDB). Each database gets an index on the book's key column, its best case. Before anything is timed, the benchmark verifies that every engine returns the identical answers. Then the same benchmark grows the book to 2 million rules and re-measures everything. The code ships in the repository.
⚡ The result
Winnow decides which of 200,000 standing rules an event triggers in about 0.7 microseconds, roughly 10× faster than a traditional database with its best index and hundreds of times faster than the rest. Sustaining 100,000 events a second, around the clock, costs about $27 a year, a tenth of one processor core. Grow the book to 2 million rules and the traffic tenfold, and Winnow's bill is still ~$38 a year; the database paths grow into thousands, and into seven figures the moment the rules stop fitting one shared index.
(Units: µs is a microsecond, a millionth of a second; ms is a millisecond, a thousandth. A payment authorization budget is typically tens of milliseconds; a web page render, a few hundred.)
The test🔗
An event arrives; the engine must answer: which of the 200,000 rules fire? Each rule has the form "this merchant, amounts in this band, score at least this": about 20 rules per merchant across 10,000 merchants. That is the shape behind fraud rule books, offer eligibility, and alert routing. Every engine returns the identical rule set for every event, cross-checked before timing.
The databases run with an index here, on purpose. This book has an obvious key column (the merchant), so the databases get their best case, the configuration a competent team would actually deploy.
Winnow can index the book two ways (a database can only do the second):
- a rule index: each rule is filed under its most distinctive condition, so an incoming event checks only the handful of rules it could possibly trigger; and
- a column index: the rules themselves are stored as a table and their conditions indexed, exactly what a database does, but answered with Winnow's index arithmetic instead of SQL.
How much faster🔗
Which of 200,000 standing rules fire: time per event← shorter is faster · log scale
Even against a database with an index on the key column (its best case), both Winnow paths win. The column index is ~20× faster than the indexed database; the rule index handles arbitrary, mixed rules, and the next section measures it at 2 million.
- Both Winnow paths beat the indexed database. Even with its key index, the traditional database runs the same "find candidates, then verify" strategy, but pays to parse and plan SQL on every event. Winnow skips that: the key's index prunes 200,000 rules to ~20 candidates, direct index arithmetic finishes them, and the hot path reuses its working memory between events to keep per-event time flat. The analytics database, with its key index, carries the per-query overhead of a batch reporting engine, not a decision engine.
- Two indexes for two situations. The column index is fastest when the rules share one shape (as here). The rule index handles arbitrary, mixed rules, each keying on whatever column is most selective for it, which is what a real, grown rule book looks like.
Growing without fear🔗
Two things grow in production: the rule book and the traffic. So the same benchmark runs the book at 200,000 and at 2,000,000 rules in one process (10× growth in breadth: 100,000 merchants at the same ~20 rules each, the way real books grow), and prices every engine at 10,000 and at 100,000 events per second. First, what growing the book does to each decision:
Time per event as the book grows 10× · 200k → 2M rules← shorter is faster · log scale
Ten times the rules costs Winnow 40%, not 10×. An event still checks only the ~20 candidate rules its key selects, so the work tracks the candidates, not the book. Anything that reads the book (a scan, or a database without a usable index) grows linearly with it: the hand-written scan went 41 µs → 416 µs, exactly 10×.
Traffic is the other axis, and it is simpler: every engine's core count grows in a straight line with event rate, so the only question is the slope: the per-event time above. Here is the bill for both book sizes, priced at a typical cloud rate (~$0.043 per core-hour):
Annual cloud bill · 100,000 events/s, around the clock · 200k vs 2M rules← cheaper is better · log scale
Growing the book 10× barely moves Winnow's bar (~$27 → ~$38 a year, a tenth of one core). Because cost is linear in traffic, the 10,000 events/s picture is every bar divided by ten (Winnow at ~$3 to $4 a year), and the gaps between engines stay identical at any rate.
What this chart says about growth:
- The worst corner is still a rounding error. Take the book from 200,000 to 2 million rules and the traffic from 10,000 to 100,000 events a second, 10× on both axes at once. Winnow's bill goes from ~$3 to ~$38 a year, still a tenth of one core. You can plan a 10× year without a capacity meeting.
- The database's affordable line is conditional. The indexed rows stay cheap only while every rule keys on the same column, so one index serves the whole book. Real books drift: rules arrive keyed on country, device, hour, velocity. Each new shape either gets its own index (a write tax on every update, multiplied per index) or drops the database to the no-index line, where the same growth story reads $13K → $1.6M a year. Winnow's rule index files each rule under whatever condition is most selective for that rule; a mixed book stays on the microsecond line. There is no cliff to fall off.
- The book can grow live. Registering and indexing all 200,000 rules takes ~160 ms; rebuilding the index for the full book of 2 million rules takes under two seconds. And updates never pause decisions: reads take a frozen snapshot while changes are published beside it in one step (measured in the mirror direction below, where throughput is unchanged with a writer mutating data in flight).
The other direction: which records match this rule?🔗
Everything above asks "which rules does this event trigger?". The mirror question, "which of my millions of records match this rule?", is what segmentation, backtesting, and campaign targeting ask, and Winnow wins it by a wider margin, because here the databases have no usable index at all. A rule book holds thousands of rules, each looking at a different combination of columns; indexing every combination is impossible, and every extra index taxes every update. So a database evaluating arbitrary rules scans. Winnow never scans: every column is already a compressed index, and a rule is answered by set arithmetic over pre-built summaries.
Measured on one rule with ten conditions spanning ten columns over 3 million records (identical answers cross-checked, as always):
Time per decision← shorter is faster · log scale
Each gridline is 10× slower than the one before it. The databases must read millions of rows to answer one decision; Winnow reads none. To sustain 100,000 decisions a second: Winnow ~$90/year (¼ core); the analytics database ~$124K (~330 cores); the traditional database ~$2.0M (~5,400 cores).
The gap is structural, not a tuning trick: no rows to read, and no SQL to parse and plan per decision. A rule compiles once, then just runs. And the speed holds while the data changes:
Decisions per second, one machinelonger is more · log scale
Winnow holds ~12M decisions/second whether the data is static or updated live, and its slow tail stays put at 10 µs. No locks on the read path: every decision reads a frozen snapshot while updates are swapped in whole. The lock-based store makes readers queue behind the writer, so its throughput dips and its slow tail grows by a third the moment updates start. Databases coordinate readers and writers the same way.
And when the record side does have a usable index, Winnow still wins the database's best workload:
- A selective key + filters. When one condition pins the search to a handful of records (a specific merchant, account, or app), Winnow uses that condition's index to find the few survivors and checks the remaining conditions against only those, the same "seek, then filter" a database index performs. Measured on exactly that shape (2 million rows): Winnow answers in ~1.2 µs, about 11× faster than the traditional database with its index (~13 µs), and roughly 370× and 520× faster than the hand-written scan and the indexed analytics database. (An earlier version of Winnow lost this comparison about 50 to 1; the current engine wins it outright.)
- A combination that's only selective together. When no single column narrows the search but a pair does, you can declare a composite index on the pair; rules that match it resolve in one small lookup, measured at roughly 100× faster on those rules (1 to 2 million rows), with no change to how the rules are written.
Honest conditions🔗
- Measured on one 16-core (32-thread) desktop workstation (AMD Ryzen 9 9950X3D-class, 128 GB RAM), July 2026; every engine runs in memory, and the 200k and 2M rule books are measured in the same benchmark run. On the record side the advantage grows with data: re-measured at 10 million rows, the traditional database takes ~196 ms per decision while Winnow takes ~6.6 µs (~30,000×). The analytics database's time barely grows with data because it is dominated by a fixed per-query overhead, which is exactly what rules it out for work at high decision rates, at any size.
- The book of standing rules is uniform on purpose (every rule keys on merchant), which is the database's best case: one index serves the whole book. It is also why we report the rule index alongside the faster column index: the rule index is the path that keeps its speed when the book stops being uniform. Growth is modeled in breadth (more merchants, constant ~20 rules each), the way real books grow; a book that instead piles thousands of rules onto one key would slow every engine's candidate step alike.
- The test rules are specific (each matches almost no records), which is the realistic hot path: most rules don't fire for most events, and fast rejection is what a screening engine does all day. For broad rules that match a large fraction of the data, an analytics database's scan narrows the gap; that batch-analytics shape is its home turf, not Winnow's target.
- The databases are excellent tools used as intended (reporting, ad hoc analytics). This comparison is about a different job: millions of small, arbitrary, many-column rule decisions a second on live data, which is what Winnow is built for.