Stress-tested across realistic payload widths and rule coverage.
The benchmark corpus exercises nested events, lookups, windows, ONNX model signals, vector similarity, regex, geo, temporal rules, SQL-style expressions, and decision reduction across JSON, Arrow IPC, Avro, and Protobuf. Records/sec shows event evaluation rate; GiB/sec shows how much input volume the engine processed.
Format summary
Records/sec answers how many events the engine evaluated. GiB/sec normalizes for record width and is the better capacity number when comparing JSON and binary formats.
| Format | OK runs | Median engine rec/s | Max engine rec/s | Median throughput | Max throughput | Median p95 batch latency |
|---|---|---|---|---|---|---|
| JSON / NDJSON | 96 | 224,119 | 628,828 | 0.80 GiB/s | 3.02 GiB/s | 129.4 ms |
| Arrow IPC | 48 | 330,209 | 654,322 | 1.37 GiB/s | 3.09 GiB/s | 39.9 ms |
| Avro | 54 | 417,239 | 665,936 | 0.65 GiB/s | 2.89 GiB/s | 48.5 ms |
| Protobuf | 54 | 427,206 | 682,874 | 0.48 GiB/s | 2.87 GiB/s | 46.4 ms |
Payload-size scenarios
The requested 1KB and 2KB targets both resolved to about 2.3KB because the full corpus has a minimum realistic field footprint. Wider records expose the JSON parse/projection cost, while Arrow and typed formats hold up better.
| Actual payload | Format | Runs | Median rec/s | Max rec/s | Median throughput | Median p95 |
|---|---|---|---|---|---|---|
| 2.2KB | JSON / NDJSON | 34 | 344,426 | 583,868 | 0.74 GiB/s | 129.4 ms |
| 2.2KB | Arrow IPC | 12 | 430,870 | 615,454 | 1.34 GiB/s | 58.2 ms |
| 2.2KB | Avro | 12 | 474,124 | 635,529 | 0.53 GiB/s | 56.4 ms |
| 2.2KB | Protobuf | 12 | 431,523 | 682,874 | 0.33 GiB/s | 58.1 ms |
| 2.2KB | JSON / NDJSON | 25 | 303,622 | 628,828 | 0.65 GiB/s | 153.5 ms |
| 2.2KB | Arrow IPC | 12 | 437,063 | 654,322 | 1.36 GiB/s | 63.2 ms |
| 2.2KB | Avro | 12 | 477,995 | 665,936 | 0.53 GiB/s | 56.0 ms |
| 2.2KB | Protobuf | 12 | 445,778 | 653,072 | 0.34 GiB/s | 60.7 ms |
| 5.0KB | JSON / NDJSON | 19 | 213,201 | 417,086 | 1.03 GiB/s | 212.1 ms |
| 5.0KB | Arrow IPC | 9 | 281,187 | 486,119 | 1.13 GiB/s | 39.2 ms |
| 5.0KB | Avro | 12 | 446,314 | 639,207 | 0.96 GiB/s | 64.1 ms |
| 5.0KB | Protobuf | 12 | 442,200 | 613,509 | 0.84 GiB/s | 59.3 ms |
| 10.1KB | JSON / NDJSON | 9 | 114,415 | 263,478 | 1.10 GiB/s | 108.4 ms |
| 10.1KB | Arrow IPC | 9 | 285,133 | 482,619 | 1.82 GiB/s | 39.4 ms |
| 10.1KB | Avro | 9 | 231,530 | 508,048 | 0.94 GiB/s | 46.2 ms |
| 10.1KB | Protobuf | 9 | 254,281 | 496,850 | 1.01 GiB/s | 46.2 ms |
| 15.0KB | JSON / NDJSON | 9 | 105,571 | 210,611 | 1.51 GiB/s | 100.9 ms |
| 15.0KB | Arrow IPC | 6 | 245,694 | 355,025 | 2.14 GiB/s | 30.3 ms |
| 15.0KB | Avro | 9 | 250,919 | 486,458 | 1.49 GiB/s | 42.5 ms |
| 15.0KB | Protobuf | 9 | 294,319 | 477,055 | 1.77 GiB/s | 37.2 ms |
Batch-size impact
Larger batches improve engine throughput by reducing per-call overhead, but they increase per-batch latency. This is the practical tradeoff for streaming deployments.
| Batch rows | Runs | Median engine rec/s | Median throughput | Median p95 batch latency |
|---|---|---|---|---|
| 2,048 | 67 | 127,806 | 0.42 GiB/s | 24.3 ms |
| 8,192 | 67 | 274,627 | 0.85 GiB/s | 41.9 ms |
| 32,768 | 64 | 447,664 | 1.06 GiB/s | 86.4 ms |
| 100,000 | 40 | 590,417 | 1.00 GiB/s | 188.1 ms |
| 1,000,000 | 14 | 459,412 | 1.23 GiB/s | 1394.5 ms |
Best observed engine runs by format
Best rows are useful for ceiling checks, not sizing promises. Use the median tables above for planning.
| Format | Actual payload | Records | Batch rows | Engine rec/s | Input throughput | p95 | Rules fired |
|---|---|---|---|---|---|---|---|
| JSON / NDJSON | 2.2KB | 1,000,000 | 1,000,000 | 628,828 | 1.35 GiB/s | 1590.3 ms | 1,047 |
| Arrow IPC | 2.2KB | 100,000 | 100,000 | 654,322 | 2.03 GiB/s | 152.8 ms | 1,047 |
| Avro | 2.2KB | 500,000 | 100,000 | 665,936 | 0.74 GiB/s | 163.7 ms | 1,047 |
| Protobuf | 2.2KB | 500,000 | 100,000 | 682,874 | 0.52 GiB/s | 154.9 ms | 1,047 |
15KB JSON stress rows
These are the wide JSON scenarios closest to the 15KB+ payload target. They show where parser and projection costs dominate and why batch size matters.
| Records | Batch rows | Engine rec/s | Input throughput | p95 batch latency | Max RSS |
|---|---|---|---|---|---|
| 100,000 | 2,048 | 63,538 | 0.91 GiB/s | 59.0 ms | 2.9GB |
| 100,000 | 8,192 | 145,233 | 2.08 GiB/s | 57.1 ms | 2.9GB |
| 100,000 | 32,768 | 202,717 | 2.90 GiB/s | 198.8 ms | 4.2GB |
| 500,000 | 2,048 | 56,230 | 0.81 GiB/s | 55.0 ms | 4.2GB |
| 500,000 | 8,192 | 105,571 | 1.51 GiB/s | 100.9 ms | 4.2GB |
| 500,000 | 32,768 | 210,611 | 3.02 GiB/s | 187.4 ms | 4.2GB |
| 1,000,000 | 2,048 | 52,684 | 0.75 GiB/s | 55.5 ms | 4.2GB |
| 1,000,000 | 8,192 | 98,402 | 1.41 GiB/s | 118.5 ms | 4.2GB |
| 1,000,000 | 32,768 | 206,356 | 2.96 GiB/s | 209.7 ms | 4.2GB |
Run the same benchmark on your hardware.
The benchmark harness is intended for local capacity planning. Re-run it with your CPU, payloads, rules, and batch settings before making sizing decisions.