AtrekesLibHFTDocumentationPerformance

Measurement

Latency needs a boundary.

LibHFT publishes percentiles only with a named workload, transport, rate and measurement path. The fastest number is less useful than a result another engineer can interpret and reproduce.

p50 · p99 · p99.94.5M messages per transport50,000 msg/s

Benchmark contract

Name every operation the clock includes.

A valid comparison fixes the message path and explains whether timing includes encoding, validation, session processing, transport enqueue, network traversal, peer work or a response. LibHFT keeps codec, session, loopback and wire measurements distinct.

  1. Disclose hardware, OS, compiler/runtime, affinity and tuning.
  2. State warm-up, sample count, duration and offered rate.
  3. Use the same message fields, validation and business-field extraction across engines.
  4. Report distributions and tail percentiles—not only minimum or average.
  5. Retain raw samples or machine-readable summaries with the source revision.

Graphical workload guide

Follow the messages. See where the clock starts.

These are the four current canonical session scenarios from the retained benchmark contract. The shaded interval is measured; grey dashed work is excluded. Both timestamps use one endpoint’s clock, so the measurement does not need synchronized host clocks.

The canonical harness measures actual-start service time, not missed schedule slots. The separate HP open-loop campaign includes scheduler delay and has its own diagram. Always keep the load model attached to a result.

Order submission → acknowledgement · Market-data request → full-book snapshot · Market data → derived order → acknowledgement · Completed tick → reaction-order arrival

Shaded: inside the clockGrey dashed: outside the clock

Swipe the diagram horizontally, or open it at full size.

Order submission → acknowledgement

nos_er — The client builds and sends a NewOrderSingle (35=D). The server parses it and derives a New acknowledgement (35=8, 150=0, 39=0) from that order; the client parses and checks the report.

Order round trip · nos_er
Client clock. t0 is before order construction and send; t1 is after reply parsing and required extraction/checks. This is an order-entry acknowledgement, not a trade fill. Open diagram ↗
View captured FIX messages for this test

Captured sample FIX messages

One complete, correlated chain from the synthetic QuickFIX/C++ functional audit. These are actual captured bytes illustrating the current canonical wire shape, not messages from the older transport campaign or measured latency samples.

The acknowledgement echoes order 11=1, symbol LCOM1, buy side, quantity 1000 and price 10000.00000. ExecType 150=0 and OrdStatus 39=0 mean New: CumQty is 0, LeavesQty is 1000 and AvgPx is 0. No LastQty/LastPx fill fields are present.

1. CLIENT → SERVER · NewOrderSingle 35=D

8=FIX.4.4|9=132|35=D|34=2|49=CLIENT|52=20261003-00:42:20.433|56=SERVER|
11=1|21=1|38=1000|40=2|44=10000.00000|54=1|55=LCOM1|60=20260703-12:00:00.000|
10=201|

2. SERVER → CLIENT · ExecutionReport · New acknowledgement 35=8

8=FIX.4.4|9=182|35=8|34=2|49=SERVER|52=20261003-00:42:20.433|56=CLIENT|
6=0.00000|11=1|14=0|17=TCP-EXEC|37=TCP-ORDER|38=1000|39=0|44=10000.00000|54=1|55=LCOM1|60=20260703-12:00:00.000|150=0|151=1000|
10=060|

| represents SOH (ASCII 0x01). Remove display line breaks and restore SOH to recover the exact message, including valid BodyLength (9) and CheckSum (10). FIX SendingTime (52) is a wall-clock field, not the monotonic measurement clock: do not subtract these timestamps to estimate latency. Tag 60 retains the fixed July fixture time.

Download the original synthetic wire capture → · Download all checked examples and source hashes →

Market-data request → full-book snapshot

md — The client requests ten levels (35=V, 264=10). The feed derives a snapshot (35=W, 268=20): ten bids and ten offers. No order or ExecutionReport is part of this scenario.

Market-data round trip · md
Client clock. t0 is before request construction/send; t1 is after the full snapshot is parsed and the required book fields are checked. Open diagram ↗
View captured FIX messages for this test

Captured sample FIX messages

One complete, correlated chain from the synthetic QuickFIX/C++ functional audit. These are actual captured bytes illustrating the current canonical wire shape, not messages from the older transport campaign or measured latency samples.

Request 262=1 asks for 264=10 levels and both bid/offer types. Its snapshot echoes the request ID and symbol; 268=20 counts twenty entries, not twenty levels. The complete wire example includes all ten bid/offer pairs in order.

1. CLIENT → SERVER · MarketDataRequest 35=V

8=FIX.4.4|9=113|35=V|34=2|49=CLIENT|52=20261003-00:42:26.939|56=SERVER|
146=1|55=LCOM1|262=1|263=0|264=10|265=0|267=2|269=0|269=1|
10=083|

2. SERVER → CLIENT · MarketDataSnapshotFullRefresh 35=W

8=FIX.4.4|9=688|35=W|34=2|49=SERVER|52=20261003-00:42:26.939|56=CLIENT|
55=LCOM1|262=1|268=20|
269=0|270=10000.00000|271=1000|269=1|270=10001.00000|271=1000|
269=0|270=9999.99000|271=1010|269=1|270=10001.01000|271=1010|
269=0|270=9999.98000|271=1020|269=1|270=10001.02000|271=1020|
269=0|270=9999.97000|271=1030|269=1|270=10001.03000|271=1030|
269=0|270=9999.96000|271=1040|269=1|270=10001.04000|271=1040|
269=0|270=9999.95000|271=1050|269=1|270=10001.05000|271=1050|
269=0|270=9999.94000|271=1060|269=1|270=10001.06000|271=1060|
269=0|270=9999.93000|271=1070|269=1|270=10001.07000|271=1070|
269=0|270=9999.92000|271=1080|269=1|270=10001.08000|271=1080|
269=0|270=9999.91000|271=1090|269=1|270=10001.09000|271=1090|
10=218|

| represents SOH (ASCII 0x01). Remove display line breaks and restore SOH to recover the exact message, including valid BodyLength (9) and CheckSum (10). FIX SendingTime (52) is a wall-clock field, not the monotonic measurement clock: do not subtract these timestamps to estimate latency. Tag 60 retains the fixed July fixture time.

Download the original synthetic wire capture → · Download all checked examples and source hashes →

Market data → derived order → acknowledgement

md_nos_er — The client requests and parses the same ten-level book, then derives an order from its received values. The server parses that order and returns the derived acknowledgement. This is the current reactive scenario—not the retired order → market data + report approximation.

Market data to order · md_nos_er
Client clock. One interval covers V → W → D → 8: two request/reply legs plus client-side book checks and order derivation. t1 follows final report parsing and required checks. Open diagram ↗
View captured FIX messages for this test

Captured sample FIX messages

One complete, correlated chain from the synthetic QuickFIX/C++ functional audit. These are actual captured bytes illustrating the current canonical wire shape, not messages from the older transport campaign or measured latency samples.

The received marker 262=1 is odd, so the client derives a buy (54=1). It uses the parsed best ask 10001.00000 for 44 and the ask size 1000 for 38 (within the lot/cap bounds). Order 11=1 carries the same marker; the final acknowledgement echoes these derived values.

1. CLIENT → SERVER · MarketDataRequest 35=V

8=FIX.4.4|9=113|35=V|34=2|49=CLIENT|52=20261003-00:42:35.638|56=SERVER|
146=1|55=LCOM1|262=1|263=0|264=10|265=0|267=2|269=0|269=1|
10=079|

2. SERVER → CLIENT · MarketDataSnapshotFullRefresh 35=W

8=FIX.4.4|9=688|35=W|34=2|49=SERVER|52=20261003-00:42:35.638|56=CLIENT|
55=LCOM1|262=1|268=20|
269=0|270=10000.00000|271=1000|269=1|270=10001.00000|271=1000|
269=0|270=9999.99000|271=1010|269=1|270=10001.01000|271=1010|
269=0|270=9999.98000|271=1020|269=1|270=10001.02000|271=1020|
269=0|270=9999.97000|271=1030|269=1|270=10001.03000|271=1030|
269=0|270=9999.96000|271=1040|269=1|270=10001.04000|271=1040|
269=0|270=9999.95000|271=1050|269=1|270=10001.05000|271=1050|
269=0|270=9999.94000|271=1060|269=1|270=10001.06000|271=1060|
269=0|270=9999.93000|271=1070|269=1|270=10001.07000|271=1070|
269=0|270=9999.92000|271=1080|269=1|270=10001.08000|271=1080|
269=0|270=9999.91000|271=1090|269=1|270=10001.09000|271=1090|
10=214|

3. CLIENT → SERVER · NewOrderSingle 35=D

8=FIX.4.4|9=132|35=D|34=3|49=CLIENT|52=20261003-00:42:35.638|56=SERVER|
11=1|21=1|38=1000|40=2|44=10001.00000|54=1|55=LCOM1|60=20260703-12:00:00.000|
10=216|

4. SERVER → CLIENT · ExecutionReport · New acknowledgement 35=8

8=FIX.4.4|9=182|35=8|34=3|49=SERVER|52=20261003-00:42:35.638|56=CLIENT|
6=0.00000|11=1|14=0|17=TCP-EXEC|37=TCP-ORDER|38=1000|39=0|44=10001.00000|54=1|55=LCOM1|60=20260703-12:00:00.000|150=0|151=1000|
10=075|

| represents SOH (ASCII 0x01). Remove display line breaks and restore SOH to recover the exact message, including valid BodyLength (9) and CheckSum (10). FIX SendingTime (52) is a wall-clock field, not the monotonic measurement clock: do not subtract these timestamps to estimate latency. Tag 60 retains the fixed July fixture time.

Download the original synthetic wire capture → · Download all checked examples and source hashes →

Completed tick → reaction-order arrival

tick_to_trade — The feed constructs a top-of-book snapshot (35=W, 268=2) before starting the clock. The trading client parses the tick and derives a NewOrderSingle. There is no acknowledgement leg.

Tick to trade · tick_to_trade
Feed clock. t0 is immediately before writing the completed tick; t1 is the first instruction of the feed-side application callback after engine framing/parsing of the returned order. Tick construction and subsequent benchmark marker/extraction checks are outside timing; those checks can still invalidate the row. Open diagram ↗
View captured FIX messages for this test

Captured sample FIX messages

One complete, correlated chain from the synthetic QuickFIX/C++ functional audit. These are actual captured bytes illustrating the current canonical wire shape, not messages from the older transport campaign or measured latency samples.

The tick is top-of-book only: 268=2, one bid and one offer. Marker 262=1 produces buy order 11=1 at the parsed ask 10001.00000 for quantity 1000. No 35=8 is sent in the headline tick-to-trade workflow.

1. SERVER → CLIENT · MarketDataSnapshotFullRefresh 35=W

8=FIX.4.4|9=138|35=W|34=2|49=SERVER|52=20261003-00:42:39.983|56=CLIENT|
55=LCOM1|262=1|268=2|
269=0|270=10000.00000|271=1000|269=1|270=10001.00000|271=1000|
10=005|

2. CLIENT → SERVER · NewOrderSingle 35=D

8=FIX.4.4|9=132|35=D|34=2|49=CLIENT|52=20261003-00:42:39.984|56=SERVER|
11=1|21=1|38=1000|40=2|44=10001.00000|54=1|55=LCOM1|60=20260703-12:00:00.000|
10=223|

| represents SOH (ASCII 0x01). Remove display line breaks and restore SOH to recover the exact message, including valid BodyLength (9) and CheckSum (10). FIX SendingTime (52) is a wall-clock field, not the monotonic measurement clock: do not subtract these timestamps to estimate latency. Tag 60 retains the fixed July fixture time.

Download the original synthetic wire capture → · Download all checked examples and source hashes →

Adapted from the sequence diagrams used by LibHFT’s comparison notebook and HTML report, with the current scenario shapes and timing boundaries. These are explanatory schematics, not new measurements. See codec microbenchmark operation diagrams →

Sustained C++ FIX transport campaign

One session, one rate, five transport paths.

The retained 20 September 2026 reference campaign compares a sustained C++ FIX response workload at 50,000 requests per second. Each transport records three 30-second measurement windows after warm-up: 4.5 million responses per transport.

Transportp50p99p99.9Maximum
Kernel TCP13.577 µs17.935 µs23.523 µs109.617 µs
Solarflare Onload5.560 µs6.044 µs6.593 µs19.537 µs
Mellanox VMA6.142 µs6.701 µs7.183 µs20.516 µs
Solarflare TCPDirect4.702 µs4.976 µs5.363 µs13.581 µs
Mellanox SocketXtreme5.788 µs6.620 µs7.702 µs22.113 µs

Common HP open-loop v4 campaign dated 20 September 2026. Lower is better. These values belong to this workload and must not be merged with separate transport-floor or raw-Ethernet campaigns.

Parity before speed

An adapter must do the same work to enter the comparison.

The qualified 3 October 2026 codec campaign covers 25 adapters in five languages. Its converted-values-v2 contract checks converted numeric values and complete business-field sets through each public parser API. All 320 isolated text/numeric probes pass. D/8 parse labels perform the same complete checked field work; W separates top-of-book checks from all twenty entries. llfix supplies build results only. These are codec admission gates, not full-session conformance or capacity. Read the current method and evidence →

25admitted codec adapters
5benchmark implementation languages
320isolated field-work probes

Interpretation

Do not compare measurements with different semantics.

CODEC

Encode/decode

Useful for isolating message work; it excludes session state and the real network.

SESSION

Protocol processing

Adds sequencing, validation, persistence and response logic at a declared boundary.

TRANSPORT

Application-to-wire

May include encode and NIC enqueue but not the complete peer round trip.

ROUND TRIP

Request and response

Includes both endpoints and the selected network path; topology becomes part of the result.

Hardware changes the answer.

NIC generation, firmware, CPU isolation, NUMA placement, runtime configuration and rate can move both the median and the tail. Treat published data as engineering evidence and rerun the target deployment.

Reproducibility checklist

What to retain with a result.

  • Engine and dependency revisions, compiler/runtime versions and build flags.
  • CPU, NIC, firmware, driver and vendor-stack versions.
  • Affinity, isolation, frequency, SMT, NUMA and interrupt placement.
  • Exact FIX payload, dictionary, validation policy, store mode and transport.
  • Warm-up, rate, duration, samples, drops, errors and raw percentile inputs.