High Dynamic Range (HDR) Histogram for recording and analyzing value distributions with configurable precision across wide dynamic ranges.
npx @tessl/cli install tessl/maven-org-hdrhistogram--hdr-histogram@2.2.0HdrHistogram provides High Dynamic Range (HDR) histograms for recording and analyzing value distributions with configurable precision across wide dynamic ranges. It enables accurate measurement of latency, response times, and other metrics without losing precision due to quantization effects.
<dependency>
<groupId>org.hdrhistogram</groupId>
<artifactId>HdrHistogram</artifactId>
<version>2.2.2</version>
</dependency>// Core histogram classes
import org.HdrHistogram.Histogram;
import org.HdrHistogram.ConcurrentHistogram;
import org.HdrHistogram.DoubleHistogram;
// Base classes and interfaces
import org.HdrHistogram.AbstractHistogram;
import org.HdrHistogram.ValueRecorder;
import org.HdrHistogram.DoubleValueRecorder;
// Recorder classes for continuous recording
import org.HdrHistogram.Recorder;
import org.HdrHistogram.SingleWriterRecorder;
// Iterator classes for data analysis
import org.HdrHistogram.PercentileIterator;
import org.HdrHistogram.HistogramIterationValue;import org.HdrHistogram.Histogram;
// Create histogram with 3 significant digits precision
// Can track values from 1 to 2^63 with auto-resizing
Histogram histogram = new Histogram(3);
// Record values (latencies in microseconds)
histogram.recordValue(1234); // 1.234ms latency
histogram.recordValue(5678); // 5.678ms latency
histogram.recordValue(987); // 0.987ms latency
// Analyze recorded data
long count = histogram.getTotalCount(); // Total samples: 3
double mean = histogram.getMean(); // Mean value
long p95 = histogram.getValueAtPercentile(95.0); // 95th percentile
long p99 = histogram.getValueAtPercentile(99.0); // 99th percentile
long max = histogram.getMaxValue(); // Maximum value
// Output percentile distribution
histogram.outputPercentileDistribution(System.out, 1.0);HdrHistogram uses a logarithmic bucket structure that provides:
Precision Control: The numberOfSignificantValueDigits parameter (0-5) controls measurement precision. Higher values provide more accurate percentiles at the cost of memory usage.
Value Equivalence: Values are grouped into equivalent ranges where all values in a range are considered equivalent for analysis purposes. This enables the constant space complexity.
Coordinated Omission Correction: Methods like recordValueWithExpectedInterval() help correct for coordinated omission where measurements miss high values due to system pauses.
Thread Safety Models: Multiple implementations provide different thread safety guarantees from single-threaded to fully concurrent access.
Basic histogram recording and analysis functionality for integer values.
// AbstractHistogram - Base functionality
void recordValue(long value);
void recordValueWithCount(long value, long count);
void recordValueWithExpectedInterval(long value, long expectedInterval);
long getTotalCount();
double getMean();
long getValueAtPercentile(double percentile);
void reset();Thread-safe histogram implementations for multi-threaded environments.
// Thread-safe histogram variants
AtomicHistogram atomicHist = new AtomicHistogram(highestTrackableValue, 3);
ConcurrentHistogram concurrentHist = new ConcurrentHistogram(3);
SynchronizedHistogram syncHist = new SynchronizedHistogram(3);Memory-efficient histogram implementations for specific use cases.
// Memory-optimized variants
IntCountsHistogram intHist = new IntCountsHistogram(highestTrackableValue, 3);
PackedHistogram packedHist = new PackedHistogram(highestTrackableValue, 3);
ShortCountsHistogram shortHist = new ShortCountsHistogram(highestTrackableValue, 3);Specialized Histogram Variants
Histogram implementations for recording floating-point values.
// Double value histograms
DoubleHistogram doubleHist = new DoubleHistogram(3);
ConcurrentDoubleHistogram concurrentDouble = new ConcurrentDoubleHistogram(3);
PackedDoubleHistogram packedDouble = new PackedDoubleHistogram(3);
PackedConcurrentDoubleHistogram packedConcurrentDouble = new PackedConcurrentDoubleHistogram(3);
void recordValue(double value);
double getValueAtPercentile(double percentile);Continuous recording with interval histogram snapshots for monitoring scenarios.
// Recorder classes
Recorder recorder = new Recorder(3);
SingleWriterRecorder singleWriter = new SingleWriterRecorder(3);
Histogram getIntervalHistogram();
Histogram getIntervalHistogram(Histogram histogramToRecycle);Comprehensive iteration and analysis capabilities for detailed data exploration.
// Iterator types
PercentileIterator percentileIter = new PercentileIterator(histogram, 5);
LinearIterator linearIter = new LinearIterator(histogram, 1000);
LogarithmicIterator logIter = new LogarithmicIterator(histogram, 1000, 2.0);Iterator Patterns and Analysis
Encoding, decoding, and log processing for data persistence and exchange.
// Serialization support
int encodeIntoByteBuffer(ByteBuffer buffer);
int encodeIntoCompressedByteBuffer(ByteBuffer buffer, int compressionLevel);
static Histogram decodeFromByteBuffer(ByteBuffer buffer, long minBarForHighestTrackableValue);Supporting classes for synchronization, encoding, and specialized operations.
// Utility classes
WriterReaderPhaser phaser = new WriterReaderPhaser();
Base64Helper.printBase64Binary(bytes);
ZigZagEncoding.putLong(buffer, value);Use Histogram or DoubleHistogram for simple scenarios without concurrent access requirements.
Use ConcurrentHistogram for wait-free recording with multiple threads, or SynchronizedHistogram for simpler synchronized access.
Use Recorder or SingleWriterRecorder to continuously record values while periodically extracting interval histograms for analysis.
Use PackedHistogram for sparse data distributions or IntCountsHistogram/ShortCountsHistogram when count limits allow smaller data types.
Use recordValueWithExpectedInterval() methods when measurements might miss high values due to coordinated system pauses.