Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Run the smoke bench and read the result

How-to guide · for anyone who wants a measurement from this machine and needs to know what it is a measurement of

What you need

  • A checkout of this repository and the Rust toolchain it pins in rust-toolchain.toml.
  • Nothing running. The bench needs no daemon and no shared memory.

Run the bench

cargo run --release -p pulse-cli -- bench --count 200000 --json

It sends 200,000 Pulses, each with a 64-byte envelope, from one socket to another over the loopback interface through the reference UDP transport, and prints one JSON object with the fields below. Without --count it sends 10,000.

Always run it in the release profile. A debug build measures the compiler, not the transport. Run it more than once, because the tail moves with whatever else the host is doing.

pms bench smoke runs the same bench and prints the same fields; its flags are in The pms command line.

Check the count before anything else

Compare pulses_received with pulses_sent. In a valid run they are equal.

The bench sends as fast as one thread can, with the transport’s backpressure off. When the receiving socket’s buffer fills, the kernel drops datagrams, and the receiver stops only after five seconds pass without one. A run where pulses_received is less than pulses_sent is not a result. Its percentiles describe only the Pulses that arrived. The command still exits 0. Discard the run and repeat it. A shortfall that repeats means the receiver cannot keep pace with an unpaced sender at that count on this host.

Read the fields

FieldMeaning
pulses_sentPulses the sender sent.
pulses_receivedPulses the receiver decoded.
payload_bytesThe envelope size of every Pulse, 64.
send_elapsed_nsWall time the sender spent sending, in nanoseconds.
recv_elapsed_nsNanoseconds from the receiver’s first read to its last decode. The timeout that ends a short run is not counted.
throughput_pulses_per_secpulses_received per second of recv_elapsed_ns.
p50_ns, p99_ns, p999_nsOne-way latency at the median, the 99th and the 99.9th percentile, in nanoseconds: the receiver’s clock at decode minus the sender’s clock carried in the frame. Both are the host’s monotonic clock, so the two readings compare on one host and on no other.

What the latency includes

The sender is not paced. When it sends faster than the receiver decodes, Pulses wait in the receiving socket’s buffer, and that wait is part of their latency. While the sender stays ahead, the queue grows with every Pulse, up to what the receiving socket’s buffer holds, so the latencies depend on the count and on how far the sender gets ahead. A run that would queue more than the buffer holds drops Pulses and is not a result. The percentiles describe a burst through two sockets, not one Pulse crossing an idle path. Compare two runs by throughput, and only at the same count. Beyond the wait, the one-way latency through two sockets is mostly the loopback path’s price: encoding and decoding a Pulse is a small part of it.

What is not here

The smoke bench measures Pulse Mesh alone, over UDP loopback. It says nothing about the shared-memory ring, the HFT ring’s wait strategies and NUMA placement, or a path between two hosts.