Explore the results
One message. Every operation.
Choose a FIX message and compare encoding, checked parsing and parsing + extraction together for every language. Each table is ranked by measured p50 within its language and operation.
NewOrderSingle · 25 measured adapters · 73 operation results. Lower is better.
Compare p50 and p99 at a glance. Expand CDF & all percentiles for the top-five-engine chart and the full ranked table. Missing results are labelled, never plotted as zero.
See the NewOrderSingle message and all three tests →
Values are ns/operation. Each sample averages 32 in-process operations, not a network round trip. CDFs connect measured percentile anchors; they are reconstructed profiles, not raw-sample empirical CDFs. What each test measures →
Same-host codec comparison
C++ and C
Native FIX engines and codec libraries, including LibHFT C++, QuickFIX/C++, NexusFIX, Fix8, hffix, Fixpp and libtrading.
Encoding
Field values → FIX bytes
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT C++ | 70 | 72 |
| hffix | 197 | 200 |
| llfix (encoder) | 462 | 466 |
| NexusFIX | 542 | 552 |
| libtrading | 660 | 668 |
| QuickFIX/C++ | 3,695 | 3,711 |
| Fix8 | 4,013 | 4,040 |
| Fixpp | 4,140 | 4,162 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT C++ | 70 | 72 | 72 | 73 |
| 2 | hffix | 197 | 199 | 200 | 201 |
| 3 | llfix (encoder) | 462 | 464 | 466 | 469 |
| 4 | NexusFIX | 542 | 549 | 552 | 554 |
| 5 | libtrading | 660 | 663 | 668 | 670 |
| 6 | QuickFIX/C++ | 3,695 | 3,702 | 3,711 | 3,718 |
| 7 | Fix8 | 4,013 | 4,029 | 4,040 | 4,048 |
| 8 | Fixpp | 4,140 | 4,152 | 4,162 | 4,168 |
Checked parsing
FIX bytes → checked field values
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT C++ | 446 | 447 |
| hffix | 506 | 517 |
| NexusFIX | 1,007 | 1,014 |
| Fixpp | 1,459 | 1,463 |
| libtrading | 2,138 | 2,147 |
| QuickFIX/C++ | 3,000 | 3,018 |
| Fix8 | 7,278 | 7,307 |
| llfix (encoder) | Encoder only · no receive-parser result | |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT C++ | 446 | 446 | 447 | 449 |
| 2 | hffix | 506 | 508 | 517 | 517 |
| 3 | NexusFIX | 1,007 | 1,008 | 1,014 | 1,016 |
| 4 | Fixpp | 1,459 | 1,461 | 1,463 | 1,467 |
| 5 | libtrading | 2,138 | 2,144 | 2,147 | 2,150 |
| 6 | QuickFIX/C++ | 3,000 | 3,009 | 3,018 | 3,032 |
| 7 | Fix8 | 7,278 | 7,295 | 7,307 | 7,318 |
| — | llfix (encoder) | Encoder only · no receive-parser result | |||
Parsing + extraction
FIX bytes → extracted business fields
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT C++ | 445 | 446 |
| hffix | 498 | 511 |
| NexusFIX | 1,000 | 1,004 |
| Fixpp | 1,456 | 1,460 |
| libtrading | 2,136 | 2,144 |
| QuickFIX/C++ | 3,009 | 3,021 |
| Fix8 | 7,287 | 7,315 |
| llfix (encoder) | Encoder only · no receive-parser result | |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT C++ | 445 | 445 | 446 | 449 |
| 2 | hffix | 498 | 499 | 511 | 512 |
| 3 | NexusFIX | 1,000 | 1,002 | 1,004 | 1,005 |
| 4 | Fixpp | 1,456 | 1,458 | 1,460 | 1,462 |
| 5 | libtrading | 2,136 | 2,140 | 2,144 | 2,146 |
| 6 | QuickFIX/C++ | 3,009 | 3,016 | 3,021 | 3,029 |
| 7 | Fix8 | 7,287 | 7,302 | 7,315 | 7,327 |
| — | llfix (encoder) | Encoder only · no receive-parser result | |||
Same-host codec comparison
Java
Java Pure and Java/JNI beside QuickFIX/J, Philadelphia, Artio and Falcon. JNI timing includes one native codec call per message.
Encoding
Field values → FIX bytes
| Engine / codec | p50 | p99 |
|---|---|---|
| Philadelphia | 537 | 2,268 |
| LibHFT Java Pure | 561 | 1,578 |
| LibHFT Java/JNI | 564 | 1,311 |
| Falcon | 1,390 | 1,690 |
| Artio | 1,755 | 3,574 |
| QuickFIX/J | 1,970 | 8,131 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | Philadelphia | 537 | 544 | 2,268 | 2,421 |
| 2 | LibHFT Java Pure | 561 | 844 | 1,578 | 7,208 |
| 3 | LibHFT Java/JNI | 564 | 763 | 1,311 | 2,540 |
| 4 | Falcon | 1,390 | 1,455 | 1,690 | 6,871 |
| 5 | Artio | 1,755 | 1,985 | 3,574 | 240,086 |
| 6 | QuickFIX/J | 1,970 | 2,422 | 8,131 | 387,550 |
Checked parsing
FIX bytes → checked field values
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT Java Pure | 827 | 2,916 |
| LibHFT Java/JNI | 1,079 | 1,991 |
| Falcon | 1,088 | 4,511 |
| Philadelphia | 1,289 | 3,940 |
| QuickFIX/J | 2,440 | 8,502 |
| Artio | 2,922 | 9,429 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT Java Pure | 827 | 833 | 2,916 | 3,635 |
| 2 | LibHFT Java/JNI | 1,079 | 1,083 | 1,991 | 2,138 |
| 3 | Falcon | 1,088 | 1,095 | 4,511 | 7,469 |
| 4 | Philadelphia | 1,289 | 1,298 | 3,940 | 7,835 |
| 5 | QuickFIX/J | 2,440 | 2,457 | 8,502 | 12,875 |
| 6 | Artio | 2,922 | 3,715 | 9,429 | 409,800 |
Parsing + extraction
FIX bytes → extracted business fields
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT Java Pure | 826 | 851 |
| LibHFT Java/JNI | 1,079 | 1,115 |
| Falcon | 1,093 | 1,135 |
| Philadelphia | 1,292 | 1,313 |
| QuickFIX/J | 2,442 | 2,637 |
| Artio | 2,922 | 3,105 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT Java Pure | 826 | 830 | 851 | 945 |
| 2 | LibHFT Java/JNI | 1,079 | 1,082 | 1,115 | 1,330 |
| 3 | Falcon | 1,093 | 1,097 | 1,135 | 7,573 |
| 4 | Philadelphia | 1,292 | 1,296 | 1,313 | 7,566 |
| 5 | QuickFIX/J | 2,442 | 2,454 | 2,637 | 3,270 |
| 6 | Artio | 2,922 | 2,953 | 3,105 | 3,660 |
Same-host codec comparison
.NET
.NET Pure and .NET Native beside QuickFIX/n and the public FIX Antenna .NET Core codec. The native flavor includes its interop boundary.
Encoding
Field values → FIX bytes
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT .NET Pure | 273 | 1,651 |
| LibHFT .NET Native | 361 | 719 |
| FIX Antenna .NET Core | 3,414 | 14,387 |
| QuickFIX/n | 6,302 | 20,337 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT .NET Pure | 273 | 480 | 1,651 | 1,687 |
| 2 | LibHFT .NET Native | 361 | 710 | 719 | 726 |
| 3 | FIX Antenna .NET Core | 3,414 | 3,483 | 14,387 | 20,873 |
| 4 | QuickFIX/n | 6,302 | 6,337 | 20,337 | 33,693 |
Checked parsing
FIX bytes → checked field values
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT .NET Native | 861 | 2,837 |
| LibHFT .NET Pure | 1,312 | 3,895 |
| FIX Antenna .NET Core | 2,342 | 4,448 |
| QuickFIX/n | 6,913 | 9,253 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT .NET Native | 861 | 863 | 2,837 | 3,004 |
| 2 | LibHFT .NET Pure | 1,312 | 1,314 | 3,895 | 4,170 |
| 3 | FIX Antenna .NET Core | 2,342 | 2,365 | 4,448 | 6,414 |
| 4 | QuickFIX/n | 6,913 | 6,946 | 9,253 | 11,701 |
Parsing + extraction
FIX bytes → extracted business fields
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT .NET Native | 837 | 841 |
| LibHFT .NET Pure | 1,383 | 1,395 |
| FIX Antenna .NET Core | 2,438 | 2,495 |
| QuickFIX/n | 6,910 | 7,068 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT .NET Native | 837 | 839 | 841 | 859 |
| 2 | LibHFT .NET Pure | 1,383 | 1,389 | 1,395 | 1,399 |
| 3 | FIX Antenna .NET Core | 2,438 | 2,457 | 2,495 | 6,493 |
| 4 | QuickFIX/n | 6,910 | 6,939 | 7,068 | 11,636 |
Same-host codec comparison
Rust
LibHFT Rust, FerrumFIX, DFX, fixer-rs, TrueFix and NanoFIX under the same message fixtures and measured operations.
Encoding
Field values → FIX bytes
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT Rust | 183 | 184 |
| NanoFIX | 212 | 215 |
| FerrumFIX | 1,624 | 1,659 |
| TrueFix | 2,251 | 2,266 |
| fixer-rs | 5,440 | 5,464 |
| DFX | 7,898 | 7,925 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT Rust | 183 | 183 | 184 | 185 |
| 2 | NanoFIX | 212 | 214 | 215 | 216 |
| 3 | FerrumFIX | 1,624 | 1,637 | 1,659 | 1,664 |
| 4 | TrueFix | 2,251 | 2,259 | 2,266 | 2,298 |
| 5 | fixer-rs | 5,440 | 5,454 | 5,464 | 5,474 |
| 6 | DFX | 7,898 | 7,911 | 7,925 | 8,038 |
Checked parsing
FIX bytes → checked field values
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT Rust | 646 | 650 |
| NanoFIX | 2,652 | 2,701 |
| TrueFix | 2,824 | 2,832 |
| DFX | 3,659 | 3,673 |
| fixer-rs | 5,815 | 5,835 |
| FerrumFIX | 11,368 | 11,420 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT Rust | 646 | 648 | 650 | 651 |
| 2 | NanoFIX | 2,652 | 2,690 | 2,701 | 2,708 |
| 3 | TrueFix | 2,824 | 2,828 | 2,832 | 2,836 |
| 4 | DFX | 3,659 | 3,667 | 3,673 | 3,681 |
| 5 | fixer-rs | 5,815 | 5,825 | 5,835 | 5,846 |
| 6 | FerrumFIX | 11,368 | 11,398 | 11,420 | 11,446 |
Parsing + extraction
FIX bytes → extracted business fields
| Engine / codec | p50 | p99 |
|---|---|---|
| LibHFT Rust | 636 | 639 |
| NanoFIX | 2,627 | 2,649 |
| TrueFix | 2,821 | 2,829 |
| DFX | 3,653 | 3,666 |
| fixer-rs | 5,822 | 5,840 |
| FerrumFIX | 10,875 | 10,923 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | LibHFT Rust | 636 | 638 | 639 | 642 |
| 2 | NanoFIX | 2,627 | 2,640 | 2,649 | 2,658 |
| 3 | TrueFix | 2,821 | 2,825 | 2,829 | 2,836 |
| 4 | DFX | 3,653 | 3,660 | 3,666 | 3,677 |
| 5 | fixer-rs | 5,822 | 5,831 | 5,840 | 5,849 |
| 6 | FerrumFIX | 10,875 | 10,901 | 10,923 | 10,943 |
Same-host codec comparison
Go
QuickFIX/Go is retained in the wider codec roster. There is no LibHFT Go flavor and no same-language competitor ranking to infer from this single row.
Encoding
Field values → FIX bytes
| Engine / codec | p50 | p99 |
|---|---|---|
| QuickFIX/Go | 11,626 | 370,492 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | QuickFIX/Go | 11,626 | 19,823 | 370,492 | 501,821 |
Checked parsing
FIX bytes → checked field values
| Engine / codec | p50 | p99 |
|---|---|---|
| QuickFIX/Go | 3,521 | 6,938 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | QuickFIX/Go | 3,521 | 6,565 | 6,938 | 138,349 |
Parsing + extraction
FIX bytes → extracted business fields
| Engine / codec | p50 | p99 |
|---|---|---|
| QuickFIX/Go | 3,520 | 7,026 |
CDF & all percentiles
| Rank | Engine / codec | p50 (ns) | p90 (ns) | p99 (ns) | p99.9 (ns) |
|---|---|---|---|---|---|
| 1 | QuickFIX/Go | 3,520 | 6,618 | 7,026 | 137,426 |
What the test measures
Three operations. Shared messages.
Encoding
Start with field values, populate a message and serialize it through the public builder. Framing and checksum work are included only where that adapter’s build path performs them.
Checked parsing
Parse and check the complete business-field set for D/8. For W, check symbol, entry count and best bid/offer. Numeric conversion and the typed value hash are inside timing.
Parsing + extraction
Parse, read the specified business fields and fold them into a checked sink. Depth-10 market data includes all 20 ordered bid/offer entries.
Fixtures are NewOrderSingle (35=D), ExecutionReport (35=8) and a 10-level MarketDataSnapshot (35=W). The same pinned fixtures and sample counts are used throughout.
See the actual FIX messages and a worked explanation of all nine tests →
These measurements exclude networking, Logon, sequence recovery, storage and application callbacks. There is no offered messages-per-second target in this in-process test, and the inverse of a codec timing is not sustained session capacity. Use the full-engine comparison for that question.
From bytes to measured work
What happens in each test?
The corrected converted-values-v2 contract requires complete checked field work for both D/8 parse labels. They intentionally perform the same operation; neither is a framing-only shortcut. W distinguishes top-of-book checks from full-book extraction. Build starts from values, not by parsing or echoing the input message.
Swipe diagrams sideways on a small screen, or open a diagram to zoom.
Checked parse: receive bytes, verify the required fields.
Parse and extract: the reads are inside the sample.
Build: start from values, not a received message.
In the examples, | represents the real FIX separator SOH (ASCII 0x01). Line breaks are for readability only. Restore SOH and remove those line breaks to recover the pinned input bytes; BodyLength (9) and CheckSum (10) are calculated for those bytes.
Tags 9001 and 9002 are benchmark-specific field-work hashes, not standard FIX fields or cryptographic signatures. The oracle uses type-marked converted values: unsigned integers, scale-five fixed-point prices and ASCII strings, each followed by byte 1. The fixed July timestamps belong to the fixtures, not the October measurement date. Download the pinned examples and their source hashes.
NewOrderSingle · 35=D
A day limit order to buy 100,000 AUD/NZD at 1.08245. 11 is the client order ID, 55 the symbol, 54=1 buy, 38 quantity, 40=2 limit, 44 price and 59=0 day time-in-force.
Pinned input for both parsing tests
- 1. Checked parse
parse_only - Feed the complete order into the public parser and read all nine fields:
11, 21, 55, 54, 60, 38, 40, 44, 59. Convert numeric values, fold typed values into FNV-1a and compare with9002=2863910631. No order is submitted and no session state changes. - 2. Parse and extract
parse_extract - Perform the same complete checked operation as D
parse_only. Both names remain for table compatibility, not as different amounts of field work. Text and numeric mutations independently verify each operation's reads. - 3. Build
build_D - Populate an order with the business values above through the public builder, serialize its fields and consume the output length. Sequence numbers or generated client order IDs may change between iterations. This measures constructing an order, not transmitting it or obtaining an execution.
Sample build payload · header and framing omitted
An illustrative payload assembled from the fixture’s business values, not a captured byte-for-byte result from every builder.
ExecutionReport · 35=8
An acknowledgement that the order is new, with all 100,000 units still open: 150=0 is a new execution event, 39=0 new order status, 151=100000 remaining quantity, 14=0 filled quantity and 6=0.00000 average fill price. This is not a fill report.
Pinned input for both parsing tests
- 1. Checked parse
parse_only - Parse and perform the same complete twelve-field checked operation described below. It does not update an order book or position.
- 2. Parse and extract
parse_extract - Parse, read and hash twelve values: order ID (
37), execution ID (17), client order ID (11), execution type (150), order status (39), symbol (55), side (54), order quantity (38), remaining quantity (151), filled quantity (14), average price (6) and transaction time (60). The typed hash includes converted quantities and fixed-point price. Compare it with9002=564350835; mismatches count as errors. - 3. Build
build_8 - Set those twelve business fields and the message header, serialize through the public builder and retain the output length. The receive-side
9002audit marker is not part of this build payload. Execution IDs, sequence numbers and field order may vary by adapter.
Sample build payload · header and framing omitted
The report’s business fields without the receive-side audit marker; not a captured wire result from every builder.
Market data snapshot · 35=W
A ten-level AUD/NZD book: ten bids and ten offers, each sized at 1,000,000. 268=20 counts entries, not levels. Each entry contains side (269=0 bid or 269=1 offer), price (270) and size (271). Best bid/offer are 1.08241 / 1.08245.
Complete pinned input · all twenty entries, with one bid/offer pair per display line
- 1. Parse only
parse_only - Give the complete depth-ten message to the parser. Read symbol (
55), entry count (268) and the first two prices (270), then compare their typed converted-value hash with9001=2376139772. This is a top-of-book check, not extraction of all twenty entries. - 2. Parse and extract
parse_extract - Parse, read request ID (
262), symbol and entry count, then visit all twenty entries in wire order. Read each entry’s side, price and size: 60 group values plus the three leading values. Convert and hash them, then compare with9002=2366019821. Reading only the first bid/offer pair cannot satisfy this check. - 3. Build
build_W - Set request ID and symbol, create
268=20and write the ten bid/offer pairs, then serialize and retain the output length. The payload contains the full book, not a two-entry shortcut. Receive-side audit tags9001and9002are omitted. Falcon has no W codec model in this campaign, so these three cells are not measured for it.
Sample build payload · all twenty entries, header and framing omitted
The complete book payload without receive-side audit tags; not a captured wire result from every builder.
Builders need not emit identical bytes: IDs, field order, FIX version and number formatting can differ. Most paths finish a framed FIX message; the pinned Java Pure path times header/body serialization without final 8/9/10 framing. That row is not a measurement of a completed on-wire message.
How the separate mutation checks prove field work
These are admission checks, not extra latency rankings. The harness mutates a field while keeping the message’s length and FIX checksum valid, but leaves the expected value hash stale. An adapter passes the probe only when it reports the hash mismatch.
- Report extraction: change
37=EX123456to37=FX123356. The9002check must detect the changed order ID. - Full-book extraction: change the second level’s prices from
1.08240 / 1.08246to1.08250 / 1.08236. The best bid/offer stay unchanged; the full9002check must notice the deeper entries. - Top-of-book check: change
55=AUD/NZDto55=BUD/NYD. The selected Wparse_onlyoperation must detect the stale9001value; rejection by a different operation cannot satisfy the probe. - Numeric conversion: change the order price from
44=1.08245to44=1.08254, or the last book size from271=1000000to271=0100000. These preserve framing but change the converted value and must fail the selected operation’s hash check.
320 isolated text/numeric probes pass. Each supported D/8/W parsing operation must reject its own mutation with a positive error count and exit code 3; rejection by another operation cannot satisfy it. Falcon has eight D/8 probes; llfix has encoder checks, not receive-parser probes. This is field-work evidence, not full FIX conformance or network performance.
Comparison boundaries
A missing cell is not a measurement.
Falcon supports the D and 8 fixtures in this campaign, but has no W codec model. Selecting market data shows it as not applicable, without timings or a rank.
llfix supplies three admitted encoder results: D, 8 and W build. Parsing selections show it as encoder-only, unranked and without invented timings. Its public source does not provide an admitted receive-parser/full-session path; a substitute parser is not an llfix engine result.
Other non-admitted, unsupported or licence-excluded targets stay in the complete engine roster. Their absence here is not evidence of slower performance. Historical, diagnostic and failed runs remain in the archive, outside these qualified tables.
The page shows 216 common D/8/W operation rows. The source report retains all 554 rows, including administrative messages and the C++ cursor/legacy variants, without mixing those paths into the default ranking.
Recorded methodology
One host. Frozen inputs. Audited windows.
| Host | SCAN · Intel Xeon E5-2698 v4 · Linux · isolated CPUs 18–19; launcher on CPUs 0–9 |
|---|---|
| Samples | 50,000 timed samples after 5,000 warm-up samples per operation; 32 operations per clock sample |
| Admission | 25/25 normal build/run gates, 320/320 extraction mutation probes, 554 operation rows and a complete clock contract |
| Host qualification | Immediate passing 120-second quiet-host preflight; five-second all-PID monitor; no competing samples at or above 5% CPU in any selected adapter window |
| Selection | Two audited timing segments with the same source, prepared runtimes, fixtures, CPU affinity and sample counts. Contaminated windows were excluded and repaired, not averaged into the ranking. |
| Campaign date | 2–3 October 2026. This is a pinned historical codec snapshot, not an assertion about every later release or every deployment. |
The mutation audit changes wire-valid fields while leaving their expected field hash stale. A passing probe rejects the mismatch, demonstrating that the adapter reads the required fields rather than merely accepting a fixed message.
Summary CSV SHA-256: fd1afadaf5f82aef7c2a05fb09b32675f4841ad27069e1c13329cbc3e0f83ceb. Download the page’s machine-readable snapshot.
Reproduce the pinned measurement procedure
Use the source revision, prepared-manifest digest and dependency pins from the campaign record. Preparation and timing are separate; reserve the host CPU slot and review process activity before publishing a result.
python3 bench/cpp/fixbench/tools/open_source_fix_engines/open_source_fix_engine_stage2.py \
--workspace "$LIBHFT_BUILD_ROOT/stage2-workspace" \
--run-prepared --parity-audit --run-cpus 18,19 \
--iterations 50000 --warmup 5000
This command requires the previously prepared, hash-verified workspace; it is not a standalone installation command. The full campaign record documents preparation, quiet-host gates and publication checks.