- Abstract
-
Chronicle JLBH is an open-source Java library, released under the Apache Licence 2.0, that provides a high-resolution latency benchmark harness. It allows developers to measure, analyse and regress-test latency behaviour of critical code paths "in context" rather than via isolated micro-benchmarks. Key features include compensation for co-ordinated omission, configurable throughput modelling, additional probes, optional operating-system jitter tracking, and serialisation of results for CI dashboards.
This document specifies functional and non-functional requirements for Chronicle JLBH, ensuring that contributors and integrators share a common understanding of the product’s goals and constraints.
The harness targets low-latency Java applications (trading systems, micro-services, real-time analytics) that must quantify latencies at extreme percentiles under realistic load patterns.
| Term | Definition |
|---|---|
JLBH |
Java Latency Benchmark Harness - the library under specification. |
Co-ordinated Omission |
Measurement error whereby pauses/back-pressure hide worst-case latencies. |
Probe |
A named histogram that records an additional timing within the benchmark workflow. |
OS Jitter |
Kernel or scheduler-induced timing variance measured by a background thread. |
CI |
Continuous Integration environment (e.g. GitHub Actions, TeamCity). |
-
Upstream repository: GitHub - OpenHFT/JLBH
-
API reference: Javadoc
-
Tutorial series: RationalJava blog series
-
Discussion of co-ordinated omission: m.s. thread
-
Chronicle blog post on JLBH in event loops: Vanilla-Java article
JLBH is delivered as a Maven artefact (net.openhft:jlbh) and depends on Chronicle Core for low-level utilities. It may be embedded in unit tests, standalone mains, or invoked as an EventLoop handler.
-
Generate high-resolution histograms (>=35 bits) of end-to-end sample latencies.
-
Optionally compensate for co-ordinated omission by adjusting the synthetic start time.
-
Model load via configurable
throughput(int, TimeUnit)and *LatencyDistributor*s. -
Provide additional named probes via
addProbe(String). -
Record OS-level jitter and present it as a separate probe.
-
Output run summaries to
PrintStreamand expose structured results viaJLBHResult. -
Serialise the final run to CSV (
JLBHResultSerializer). -
Integrate with CI (TeamCity helper emits
##teamcitystatistics lines). -
Allow execution from any thread or installation onto a Chronicle MediumEventLoop.
| Actor | Description | Technical Expertise |
|---|---|---|
Performance Engineer |
Designs latency benchmarks and analyses histograms. |
Advanced Java & performance tuning. |
Developer |
Adds JLBH tests to codebase, evaluates pull-request regressions. |
Intermediate Java. |
CI System |
Runs automated latency regression suite, ingests CSV or TeamCity stats. |
N/A (automation). |
-
Java 11 LTS and later; Java 17 recommended for current builds.
-
Linux x86-64 (primary), other POSIX OSes supported; macOS usable but CI baselines exclude it.
-
Typical CPU affinity facilities available via OpenHFT Affinity library.
-
Single-threaded harness execution; benchmarked code may span threads.
-
Measurements rely on
System.nanoTime()precision; hardware timers must be invariant. -
JVM must be started with
-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepointswhen using async-profiler concurrently. -
Library is released under the Apache Licence 2.0; contributions must comply with CLA policy.
-
JLBHOptions- builder for benchmark parameters (throughput, warm-up, runs, etc.). -
JLBHTask- user-defined callback with lifecycle methodsinit,run,warmedUp,runComplete,complete. -
JLBH- orchestrator class withstart()andeventLoopHandler(EventLoop)entry points. -
JLBHResult- immutable projection of measured data. -
JLBHResultSerializer- CSV writer for analytics pipelines.
CLI usage is demonstrated in ExampleJLBHMain and test fixtures; no dedicated GUI is provided.
None. The harness interacts with OS timers and CPU affinity via JNI where available.
Description: Collect nanosecond deltas from user code via sample(long) or sampleNanos(long).
Stimulus/Response: Upon each iteration, JLBHTask.run calls jlbh.sample(…); histogram updates occur; run summary printed at completion.
Priority: Essential.
Ensures that queue back-log does not under-represent tail latency. Enabled by default; opt-out via accountForCoordinatedOmission(false).
Developers may time sub-stages (e.g., serialisation, network round-trip) through addProbe(String) and record them independently.
A background thread measures scheduling gaps exceeding a configured threshold (recordJitterGreaterThanNs). Monitoring is enabled by default and can be disabled via recordOSJitter(false). Results are summarised alongside core latencies.
Post-run, results can be persisted for offline analysis (result.csv by default).
-
Overhead per sample must remain below 100 ns when no additional probes are active.
-
Histogram generation must support >=200 M iterations without heap pressure.
-
Harness must abort gracefully on thread interruptions or sample time-outs (
timeout(long)). -
Immutable result objects ensure thread-safe publication to external consumers.
-
Fluent builder API; sensible defaults provide a runnable benchmark in ≤10 LOC.
-
ASCII table outputs are human-readable and CI-friendly.
-
Pure-Java codebase; no native compilation steps.
-
JDK-specific optimisations (e.g., Zing support) are runtime-detected.
-
80 %+ unit-test line coverage with deterministic fixtures.
-
Code adheres to Chronicle parent POM style and SonarCloud quality gates.
The project is released under the Apache Licence 2.0 (see LICENSE.adoc).
Downstream consumers must preserve licence notices and may include JLBH in commercial or OSS products, subject to the terms therein.
- Co-ordinated Omission
-
Statistical artefact causing under-reporting of worst-case latency.
- Histogram
-
Data structure that records frequency counts in logarithmic buckets, enabling percentile extraction.
- Percentile
-
Value below which a given percentage of observations fall (e.g., 99th percentile).
public class NothingBenchmark implements JLBHTask {
private JLBH jlbh;
public void init(JLBH jlbh) { this.jlbh = jlbh; }
public void run(long startTimeNS) {
jlbh.sample(System.nanoTime() - startTimeNS);
}
public static void main(String[] args) {
new JLBH(new JLBHOptions()
.throughput(1_000_000)
.iterations(10_000)
.jlbhTask(new NothingBenchmark()))
.start();
}
}-
JLBH originated within the Chronicle Software open-source stack and is actively maintained. See https://github.com/OpenHFT/JLBH.
-
The API reference highlights the focus on co-ordinated omission and event-loop support. See https://www.javadoc.io/doc/net.openhft/chronicle-core/latest/net/openhft/chronicle/jlbh/JLBH.html.
-
A multi-part blog series gives practical guidance on designing realistic latency tests. See http://www.rationaljava.com/2016/04/a-series-of-posts-on-jlbh-java-latency.html.
-
Vanilla-Java’s micro-services article demonstrates embedding JLBH in an event-driven architecture. See https://vanilla-java.github.io/2016/04/02/Microservices-in-the-Chronicle-World-Part-5.html.
-
Original discussion of co-ordinated omission by Gil Tene motivates JLBH’s default settings. See https://groups.google.com/g/mechanical-sympathy/c/icNZJejUHfE.