What Is a Histogram in OpenTelemetry?
A beginner-friendly guide to the instrument that keeps the shape of your measurements: how buckets work, why averages mislead, how percentiles are estimated, and how to choose and tune histograms without wasting money.
Imagine a pizza shop that promises delivery in thirty minutes. At the end of the week, the owner looks at one number: the average delivery time is twenty-two minutes. That sounds wonderful. Yet the shop is getting angry phone calls. When the owner finally reads every single delivery slip, the truth appears. Most pizzas arrived in fifteen minutes, but one in ten arrived after an hour. The average smoothed the bad days away and hid the unhappy customers. What the owner really needed was not one number, but a picture of how all the delivery times were spread out. In OpenTelemetry, that picture is called a histogram.
This guide starts from zero. You do not need to know what a bucket is, what a percentile is, or why anyone would sort numbers into groups before sending them. We will build each idea step by step, using everyday comparisons and simple pictures, until you can explain histograms to a colleague with confidence.
1The Problem: One Number Cannot Describe Many Measurements
Before we meet the histogram, let us feel the problem it solves.
Software produces measurements by the million
Every time your web service answers a request, it takes some amount of time. Every time it sends a response, that response has some size. These are measurements, and a busy service creates millions of them every hour. You cannot send all of them to a monitoring tool without huge cost, and you cannot read all of them yourself. You need a summary.
The trap of the average
The most familiar summary is the average. Add everything up, divide by the count, and you get one friendly number. Averages are fine for things that behave evenly, such as the height of adults in a room. But software measurements are rarely even. Most requests are fast, a few are slow, and a very small number are extremely slow. The slow ones are exactly the ones that make customers leave, and the average hides them.
Consider ten requests. Nine take one second and one takes ninety-one seconds. The average is ten seconds, a number that matches no real request at all. Nine people were happy, one person was furious, and the average told you neither story.
Imagine a river whose average depth is one metre. A child told “the river is only one metre deep” might happily wade across, not knowing that part of it is three metres deep. A map of the river bed, showing how deep each stretch is, would keep that child safe. A histogram is that map for your measurements.
Many beginners believe that “a histogram is just a fancy average”. It is the opposite. An average throws away the spread of the data. A histogram exists precisely to keep that spread.
2A Quick Refresher: Metrics and Instruments
The histogram is one tool in a small toolbox, so let us remember the box.
A metric in OpenTelemetry is a measurement of something about your software, tracked over time and summarised so it stays small. Your code does not write metrics directly. Instead, it uses an instrument, an object that records measurements. OpenTelemetry offers a handful of instruments, and each one summarises its measurements in its own way.
Counter
For totals that only go up, such as requests served or errors seen.
UpDownCounter
For values that rise and fall, such as items waiting in a queue.
Gauge
For a snapshot of the latest value, such as a current temperature.
Histogram
For measurements where the spread matters, such as response times and sizes. This is our star.
The key difference is what each instrument keeps. A counter keeps one running total. A gauge keeps one latest value. A histogram keeps a small table showing how many measurements fell into each range. That table is what lets you answer questions like “how many requests were slower than one second?” long after the individual requests are forgotten.
A counter is a turnstile that clicks once per visitor. A gauge is a thermometer that shows the temperature right now. A histogram is a tally sheet where you make a mark in the right column for every visitor’s waiting time, so at the end of the day you can see how many waited a short, medium or long time.
3So, What Is a Histogram?
A plain definition first, then the reasons behind each word.
A histogram in OpenTelemetry is an instrument that records many individual measurements and summarises them as a distribution, which means a count of how many measurements fell into each of several ranges called buckets. Along with the bucket counts, it normally keeps the total number of measurements and the sum of all measured values.
That definition has three important ideas inside it.
Many measurements, one summary
You record every request’s duration, but only a small table travels onward. Ten requests or ten million requests produce a table of the same size.
Ranges called buckets
Instead of remembering exact values, the histogram sorts each measurement into a range. You lose exactness but gain a compact picture of the shape.
Counts, total and sum
Beside the buckets, the histogram knows how many measurements there were and what they added up to. This lets you still compute an average and a rate whenever you need one.
4Buckets: Sorting Measurements into Ranges
Everything about a histogram begins with its buckets.
A bucket is a range of values with a lower edge and an upper edge. When a measurement arrives, the histogram finds the bucket whose range contains it and adds one to that bucket’s count. The measurement itself is then forgotten. Only the count remains.
A worked example
Suppose you track response times in seconds, and you choose these bucket edges: one tenth, half, one, and five seconds. That creates five buckets. The first covers everything up to one tenth of a second. The second covers up to half a second. The third covers up to one second. The fourth covers up to five seconds. The fifth, called the overflow bucket, covers everything above five seconds.
| Bucket | Range of Response Time | Number of Requests |
|---|---|---|
| 1 | Up to 0.1 seconds | 620 |
| 2 | Above 0.1 up to 0.5 seconds | 280 |
| 3 | Above 0.5 up to 1 second | 70 |
| 4 | Above 1 up to 5 seconds | 25 |
| 5 | Above 5 seconds (overflow) | 5 |
From this tiny table, you can already say a lot. Out of one thousand requests, 620 were very fast, 900 were answered within half a second, 970 within a second, and only five were painfully slow. No average could have told you that.
flowchart LR
M["New measurement: 0.35 seconds"] --> C{"Which range contains it?"}
C -->|"Up to 0.1"| B1["Bucket 1"]
C -->|"0.1 to 0.5"| B2["Bucket 2: add one"]
C -->|"0.5 to 1"| B3["Bucket 3"]
C -->|"1 to 5"| B4["Bucket 4"]
C -->|"Above 5"| B5["Overflow bucket"]
The overflow bucket
There is always one more bucket than there are edges. The last bucket catches everything bigger than the largest edge. It is easy to forget, but it matters, because if too many measurements land there, your edges are too small for your data and you are losing detail exactly where problems live.
Where do the edges belong?
By convention in OpenTelemetry, a bucket includes its upper edge but not its lower edge. A measurement exactly equal to a boundary falls into the bucket that ends at that boundary. It is a small detail, but it explains why a value of exactly half a second counts in the second bucket above, not the third.
Think of a post office that sorts parcels into weight bands: up to one kilogram, up to two kilograms, up to five kilograms, and heavier. A parcel of exactly two kilograms goes into the “up to two” band. The post office does not remember each parcel’s exact weight, only how many fell into each band.
5What a Histogram Data Point Contains
Every histogram sends a standard bundle of information.
When OpenTelemetry sends a histogram to a Collector or a monitoring tool, each data point carries the same set of parts. Learning them helps you read histograms from any system.
Bucket Counts
The number of measurements that fell into each bucket, including the overflow bucket.
Bucket Boundaries
The edges that separate the buckets. They tell the reader what range each count refers to.
Count
The total number of measurements, which equals the sum of all bucket counts.
Sum
The total of all measured values. Dividing it by the count gives the average.
Minimum and Maximum
Optional extra values recording the smallest and largest measurements seen, which help with sanity checks and chart limits.
Attributes and Timestamps
The labels describing which slice of the system the data belongs to, plus the time window it covers.
What you can still calculate
Even though individual values are gone, this small bundle lets you work out several useful things. Count over time gives you the rate of events. Sum divided by count gives the average. Bucket counts give you the shape and let you estimate percentiles. Min and max, when present, give you the extremes.
A histogram quietly contains a counter inside it. Because it records the count of measurements, you get a free request-rate metric without creating a separate counter.
6Percentiles: Reading the Shape of Your Data
Percentiles are the most common question people ask of a histogram.
A percentile answers the question “what value do this many of my measurements stay below?”. The 50th percentile, also called the median, is the value below which half of all measurements fall. The 95th percentile is the value below which 95 out of every 100 measurements fall. The 99th percentile zooms in on the slowest one in a hundred.
The Typical Experience
Half of your users did better than this. It describes the ordinary case.
The Unlucky Few
Only one user in twenty had a worse experience. A popular target for service goals.
The Very Unlucky
One user in a hundred had a worse experience. Important for large systems, where one in a hundred is still many people.
The Worst Case
The single slowest measurement. Useful for spotting extremes, but too noisy to base goals on.
How a tool estimates a percentile
Because the histogram only knows how many measurements landed in each bucket, not their exact values, the tool must estimate. Imagine you want the 95th percentile of one thousand requests. You need the value below which 950 requests fall. The tool adds up bucket counts from the smallest bucket upwards until it reaches 950. It finds that the 950th request lives in a certain bucket, and then guesses its position inside that bucket by assuming the measurements are spread evenly across it.
This means the answer is an estimate, not an exact value. How good the estimate is depends on how narrow the bucket is. A wide bucket means a rough answer. A narrow bucket means a precise one.
Suppose a teacher only records how many students scored in the ranges zero to forty, forty to sixty, sixty to eighty, and eighty to one hundred. If someone asks for the score of the student ranked fifteenth out of a hundred, the teacher can say “somewhere between forty and sixty”, and can guess a number inside that range, but cannot be exact. Narrower score ranges would give a better guess.
Treating a percentile from a histogram as an exact value. If your buckets near that percentile are wide, the true value could sit anywhere inside the bucket. Always remember that percentile charts from histograms are estimates.
7The Superpower: Histograms Can Be Combined
This is the quiet reason histograms are the right tool for large systems.
Imagine you run twenty copies of the same service. Each copy measures its own response times. Now you want the 95th percentile across all twenty. You might be tempted to calculate the 95th percentile on each copy and then average those twenty numbers. This gives a wrong answer. Percentiles cannot be averaged. A busy copy and a quiet copy contribute very differently to the overall picture, and averaging their percentiles ignores that.
Histograms solve this beautifully. Because each copy reports bucket counts, you can simply add the counts together, bucket by bucket. The result is a single histogram describing all twenty copies as if they were one service. From that combined histogram, you can then estimate a correct overall percentile.
flowchart TD
A["Service copy 1: bucket counts"] --> S["Add counts bucket by bucket"]
B["Service copy 2: bucket counts"] --> S
C["Service copy 3: bucket counts"] --> S
S --> H["One combined histogram"]
H --> P["Estimate the true overall percentile"]
Combining Histograms
- Add bucket counts across instances, regions or time windows
- Produces a correct overall distribution
- Works for any number of copies of a service
- Lets you choose which percentile to ask for later
Combining Precomputed Percentiles
- Cannot be averaged or added meaningfully
- Gives wrong answers when instances carry different load
- Fixes the percentile at the moment of recording
- Offers no way to ask a different question later
Think of several schools sending the tally of exam marks in each range to the education board. The board can add the tallies and see the national picture. If each school had instead only sent “our median mark”, the board could not work out the national median, because it would not know how many students each school had or how marks were spread.
8Explicit Bucket Histograms
The classic kind, where you decide the edges in advance.
In an explicit bucket histogram, the edges between buckets are a list of numbers chosen before any measurement arrives. The SDK ships with a default list that is spread across a wide range, from very small values up to ten thousand. This default is a general-purpose guess that works tolerably for many cases, but it was designed with values like milliseconds in mind.
The unit problem
Here is a common trap. OpenTelemetry’s semantic conventions recommend measuring durations in seconds, so a typical web request might take 0.045 seconds. If you record that in seconds but keep the default edges, which start at zero, five, ten and so on, nearly every measurement falls into the very first bucket, and the histogram becomes useless. The edges must match the unit and the typical size of your data.
| Situation | Typical Values | Sensible Edge Style |
|---|---|---|
| Web request duration in seconds | A few milliseconds to several seconds | Small steps near zero, such as 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10 |
| Database query duration in seconds | Sub-millisecond to a few seconds | Even finer steps near zero, then coarser above one second |
| Response size in bytes | A few hundred bytes to several megabytes | Steps that grow by roughly a factor of ten or four |
| Batch job duration in seconds | Seconds to hours | Wide steps such as 1, 10, 60, 300, 900, 3600 |
Choosing good edges
Good edges follow three simple rules. First, cover the full realistic range of your data, including a few edges beyond the worst case you can imagine. Second, place more edges where you care most about precision. Third, put an edge exactly at any goal or threshold you care about, such as “responses should be under 300 milliseconds”, so that the count under that line is exact, not estimated.
Pick the unit first
Decide whether you record seconds, milliseconds or bytes. Edges only make sense relative to the unit.
Look at your real data range
Find the fastest, typical and slowest values from a test or from existing logs, and note them.
Place edges around what matters
Put several edges around your typical values and extra edges at your target thresholds.
Leave room for the unexpected
Add a few large edges so a rare disaster does not hide inside the overflow bucket.
Check and adjust
After running for a while, look at the bucket counts. If most of the data sits in one bucket, refine your edges.
Keeping the default edges while measuring in seconds. The result is a histogram where almost everything lands in one bucket. Charts look flat, percentiles look silly, and nobody understands why.
9Exponential Histograms
A smarter kind that chooses its own edges.
Choosing edges by hand is a nuisance, and a wrong choice hurts. OpenTelemetry therefore offers a second kind, the exponential histogram. Instead of a list of fixed edges, it uses a rule: each bucket is a fixed percentage wider than the one before it. Small values get tiny buckets and large values get bigger buckets, which is exactly what most real data needs, because the difference between one and two milliseconds matters far more than the difference between nine thousand and nine thousand and one.
The idea of scale
The rule is controlled by a single number called the scale. A higher scale makes the buckets narrower and more numerous, giving better precision. A lower scale makes the buckets wider and fewer. The clever part is that the histogram adjusts its own scale automatically. It starts with high precision, and if measurements spread across such a wide range that it would need too many buckets, it quietly lowers its scale to keep the number of buckets under a limit. You get good accuracy without ever choosing an edge.
Other pieces
An exponential histogram also keeps a separate count for measurements that are exactly zero, since zero cannot be placed on a growth-based scale, and can keep separate buckets for positive and negative values.
Imagine a ruler that automatically stretches. When you measure tiny insects it shows fine millimetre marks. When you measure an elephant, it shrinks its marks to larger steps so it still fits in your pocket. You never have to swap rulers, because the ruler adapts to what you are measuring.
| Question | Explicit Bucket Histogram | Exponential Histogram |
|---|---|---|
| Who chooses the edges? | You, in advance | The histogram, automatically |
| Setup effort | Needs careful tuning | Nearly none |
| Accuracy across wide ranges | Depends on your choices | Consistently good |
| Size per data point | Fixed by your edge list | Varies, with an upper limit |
| Backend support | Almost universal | Growing but not yet universal |
| Exact threshold counts | Yes, if you add an edge at the threshold | Approximate |
Before choosing exponential histograms, confirm that your monitoring backend understands them. If it does not, the data may be converted into a less precise form or rejected. The Collector can sometimes convert between styles, but the conversion costs accuracy.
10How a Histogram Is Recorded Inside Your Application
A short tour of what happens between a measurement and a dashboard.
You do not need to master the internals, but knowing the steps makes the whole subject less mysterious. A histogram is a synchronous instrument, which means your code records a value at the moment something happens. For example, when a request finishes, the code notes how long it took and hands that single number to the histogram.
Work finishes and a value is known
A request ends and the code measures its duration, for example 0.35 seconds.
The value is recorded with attributes
The code hands the value to the histogram, along with a few labels such as route and result.
The SDK updates the summary
For that label combination, the SDK adds one to the matching bucket, one to the count, and adds the value to the sum. The raw value is then forgotten.
A reader collects on a schedule
At regular intervals, often about once a minute, a metric reader gathers the current summaries.
An exporter sends the data
The summaries travel to a Collector or monitoring tool, where they are stored and drawn on charts.
flowchart LR
R["Request finishes: 0.35 s"] --> H["Histogram instrument"]
H --> AG["SDK adds to bucket, count and sum"]
AG --> RD["Metric reader collects each interval"]
RD --> EX["Exporter sends over OTLP"]
EX --> CO["Collector"]
CO --> BE["Backend: percentiles and heatmaps"]
What to record in a histogram
Histograms suit any measurement that is naturally a size or an amount of time and where the spread matters. Typical examples include the duration of web requests, the duration of database queries, the size of messages or responses, the time a job waits in a queue, and the number of items processed per batch.
If you find yourself wanting to know “what is the typical value and what does the worst case look like?”, you have found a perfect job for a histogram. If you only want a running total, a counter is cheaper and simpler.
11Views: Changing a Histogram Without Changing Code
You can tune histograms from the outside.
In OpenTelemetry, a view is a configuration rule that changes how a metric is summarised, without touching the code that records it. Views are especially valuable for histograms, because developers who write instrumentation inside a library cannot always know the best bucket edges for your particular system.
Change the bucket edges
A view can replace the default edges with a better list for a specific histogram, such as web request duration, so that it fits your real data range.
Switch the histogram type
A view can tell the SDK to use an exponential histogram instead of an explicit one for chosen instruments, if your backend supports it.
Remove unwanted attributes
A view can keep only a short list of attributes on a histogram, dropping risky high-cardinality ones before they ever leave the application.
Rename or drop a metric
A view can change a metric’s name or description, or switch off a histogram entirely if nobody needs it.
Advice from the instrument creator
Instrument authors can also suggest sensible bucket edges when they create a histogram, as a hint. If a view exists, the view wins. If not, the hint is used. If there is neither, the SDK falls back to its general-purpose default. This layering lets library writers offer sensible defaults while still leaving final control to the application owner.
Because views live in configuration, you can adjust histograms for an entire fleet of services without changing and redeploying application code. This is a major advantage when many teams share common libraries.
12Temporality: Cumulative and Delta Histograms
Histograms can be reported as running totals or as changes.
Like counters, histograms can be reported in two styles. A cumulative histogram reports bucket counts since the program started, so the numbers only ever grow. A delta histogram reports only what was recorded since the last report, so each report stands alone. The choice is called temporality.
| Period | New Requests in Slow Bucket | Cumulative Report | Delta Report |
|---|---|---|---|
| Minute 1 | 4 | 4 | 4 |
| Minute 2 | 6 | 10 | 6 |
| Minute 3 | 0 | 10 | 0 |
| Minute 4 | 9 | 19 | 9 |
Many open-source monitoring tools prefer cumulative reports, since a missed report is easily recovered. Some commercial platforms prefer delta reports, which can use less memory inside your application. Which one is right depends on your backend. A mismatch leads to strange charts, so choose the style your destination expects, or let a Collector convert between them.
Why this matters for percentiles
When you ask “what was the 95th percentile over the last five minutes?”, the tool must work on the difference between two cumulative snapshots, or on the sum of several delta reports. Either way, the underlying idea is the same: adding and subtracting bucket counts. This is possible only because histograms keep counts per bucket.
Reading a cumulative histogram as if it described only the last minute. A cumulative histogram describes everything since the start. To see recent behaviour, a tool must compare two snapshots. Without that step, old data drowns out new problems.
13Cost and Cardinality: Histograms Are Heavier Than Counters
The extra detail of a histogram has a price.
A counter produces one number per combination of attributes. A histogram produces one number for each bucket, plus the count and the sum, per combination of attributes. With fifteen buckets, a single histogram series can be roughly seventeen numbers where a counter would have one. Multiply that by the number of attribute combinations, and the cost grows quickly.
The multiplication problem
Imagine a histogram of request duration with attributes for route, method, status class and region. If there are twenty routes, four methods, three status classes and five regions, you already have twelve hundred combinations. With seventeen numbers each, that is over twenty thousand numbers every collection interval. Add a high-cardinality attribute such as a user identifier, and the system can drown.
A counter is like keeping one tally number per shop. A histogram is like keeping a full tally sheet with a dozen columns per shop. If you have ten shops, the sheet is manageable. If you accidentally keep a separate sheet for each customer, you will fill a warehouse with paper.
Practical ways to control cost
Use fewer, smarter buckets
Ten well-chosen edges often beat thirty poorly chosen ones. Place edges where decisions are made.
Keep attributes bounded
Use route patterns, not full web addresses, and status classes, not individual messages. Never use identifiers that are different for every request.
Use views to trim
Drop attributes you never query on, so each histogram has fewer series.
Record only what you will use
Not every duration needs a histogram. A simple counter or gauge may be enough for secondary measurements.
Problem
A team records request duration in a histogram and adds the full web address, including real order numbers, as an attribute.
Why It’s Harmful
Each unique address creates a brand-new series of seventeen or more numbers. Storage and cost explode, and queries slow down.
Correct Approach
Use the route pattern as the attribute, and leave the specific order number to traces and logs.
14Exemplars: Jumping from a Bucket to a Real Trace
A histogram can point to real examples hiding in its buckets.
A histogram tells you that fifty requests last week fell in the slowest bucket. But which requests? Why were they slow? The histogram, by design, has forgotten the details. Exemplars are a clever bridge. An exemplar is a small sample attached to a histogram bucket that records one real measurement together with the identifier of the trace it came from.
With exemplars, a chart can show dots over the histogram, each dot representing a real request. Click a dot in the slow area, and you jump straight to the full trace of that request. You move from a summary to a concrete story in one step.
flowchart LR
A["Alert: slow requests increasing"] --> B["Look at the histogram: slow bucket growing"]
B --> C["Open an exemplar from that bucket"]
C --> D["View the full trace of that request"]
D --> E["Find the slow step and read its logs"]
Imagine a customer survey summary that says “forty customers were very unhappy”. An exemplar is like a clipped-on sticky note with the reference number of one of those unhappy customers. You can pick up the phone and find out exactly what went wrong for that person.
Exemplars only help when both the metric and the trace are recorded and sent to tools that understand the link. When setting up tracing and metrics, make sure both go to a system that supports exemplars.
15Turning Histograms into Goals and Alerts
Histograms are the natural building block for service level goals.
Many teams promise their customers something like “ninety-five percent of requests will finish in under 300 milliseconds”. That sentence is really a statement about a distribution, and a histogram is the perfect tool to check it. If you place a bucket edge at 300 milliseconds, the histogram can say exactly how many requests were at or under that line, and how many were over it.
Two ways to express the same goal
Percentile Goal
“The 95th percentile of response time must stay below 300 milliseconds.” Easy to say, but relies on an estimate inside a bucket.
Fraction Goal
“At least 95 percent of requests must finish within 300 milliseconds.” With an edge at 300 milliseconds, the fraction is exact, and it is also easy to track as an error budget.
Alerting on user pain
Good alerts focus on what users feel. An alert such as “the share of requests slower than one second has exceeded five percent for ten minutes” is easy to understand, hard to ignore, and does not fire for harmless blips. A histogram makes this kind of alert possible, whereas an average-based alert would stay silent until things were already badly broken.
| Alert Idea | Needs a Histogram? | Why |
|---|---|---|
| Average response time above one second | No | Sum divided by count is enough, but it hides outliers |
| 95th percentile above 300 milliseconds | Yes | Percentiles need the distribution |
| More than 5 percent of requests slower than one second | Yes | Needs counts on each side of a threshold |
| Total request count dropped sharply | No, but a histogram includes it | The count inside a histogram acts as a counter |
Setting a goal at a threshold that does not match any bucket edge. The tool then has to guess inside a bucket, and your reported compliance may be a few percent off. Always add an edge at every threshold that appears in a promise or an alert.
16Histograms in the Collector and in Other Systems
What happens after the histogram leaves your application?
Histograms travel from the application to a Collector using the OpenTelemetry Protocol, and then onward to a monitoring backend. Along the way, a few things are worth knowing.
The Collector passes histograms through
In nearly all setups, the Collector forwards histograms unchanged, though it can add or remove attributes, batch data, and convert between cumulative and delta styles.
Open-source metrics systems
Many popular systems store explicit histograms as a family of related series: one per bucket edge showing the count up to that edge, plus a count and a sum. Newer versions of such systems also offer a native histogram format that resembles OpenTelemetry’s exponential histograms, which makes the two a natural match.
Commercial platforms
Many vendors accept OpenTelemetry histograms directly and compute percentiles for you. Support for exponential histograms varies, so always check before relying on them.
Conversions lose some accuracy
Converting an exponential histogram into explicit buckets, or the reverse, usually costs some precision. Prefer a direct path where your backend understands the format you send.
Before you finalise your histogram setup, send a few test measurements and look at the resulting chart in your backend. A thirty-minute test often reveals mismatched units, bad edges or unsupported formats long before production.
17Security and Privacy Considerations
Histograms are summaries, but their labels still deserve care.
A histogram reveals little about individual users, because it holds only counts per range. The risk comes from the attributes you attach to it, and from how widely the data is shared.
Keep personal data out of attributes
Never use names, emails or account numbers as attributes. They are both a privacy risk and a cardinality problem.
Beware of tiny groups
If an attribute slices data so finely that a bucket holds a single customer, the histogram can reveal that one person’s behaviour. Keep slices broad enough to protect individuals.
Protect the path
Use encrypted connections between your applications, Collectors and backends, and restrict who can view or edit dashboards.
Review exemplars
Exemplars link to real traces. Make sure those traces do not carry sensitive data, and limit access to trace viewers accordingly.
Assuming a metric is anonymous because it is a summary. A histogram labelled by customer, device or location can sometimes point at a single person. Always review attributes with privacy in mind.
18Best Practices and Anti-patterns
Habits that keep histograms useful and affordable.
Good habits
Use histograms for durations and sizes
Any measurement where the spread matters belongs in a histogram, not in an average.
Always set the unit and match the edges to it
Record durations in seconds, as the semantic conventions suggest, and choose edges that fit seconds.
Place edges at your thresholds
Add an edge wherever a goal, alert or promise mentions a number, so counts at that line are exact.
Prefer exponential histograms when supported
They need little tuning and stay accurate across wide ranges, if your backend understands them.
Keep attributes small and bounded
Remember that every extra label multiplies the cost of every bucket.
Combine, then calculate
Add histograms across instances first, then estimate percentiles from the combined result. Never average percentiles.
Use exemplars where possible
They turn a summary into a doorway to real traces and cut investigation time.
Mistakes to avoid
Problem
A team calculates the 95th percentile inside each service instance and then averages those numbers on the dashboard.
Why It’s Harmful
Percentiles cannot be averaged. Busy and quiet instances are given equal weight, producing a number that matches no real experience and can badly understate problems.
Correct Approach
Send bucket counts, add them across instances, and estimate the percentile from the combined histogram.
Problem
Default bucket edges are used for a histogram that records durations in seconds.
Why It’s Harmful
Nearly every measurement falls into the first bucket. Percentile charts are meaningless and slow requests are invisible.
Correct Approach
Choose edges that match the unit and range of your data, or use exponential histograms that adapt on their own.
Problem
Dozens of fine-grained buckets are added “just in case”, on top of many attributes.
Correct Approach
Choose a modest number of edges placed where decisions are made, and review attributes before release.
Why It’s Harmful
The number of stored values multiplies, costs rise sharply, and queries slow down, with little gain in useful accuracy.
Problem
Dashboards show only the average of a duration histogram, computed from sum and count.
Why It’s Harmful
The histogram’s whole purpose, revealing the spread, is thrown away. Slow outliers stay hidden behind a calm line.
Correct Approach
Chart the median together with high percentiles, and consider a heatmap that shows the whole distribution over time.
19Advantages and Trade-offs of Histograms
Histograms are powerful, but they are not free.
Advantages
- Preserve the shape of the data, not just a single summary number
- Allow percentiles to be estimated and chosen later
- Can be added together across instances, regions and time
- Stay small no matter how many measurements are recorded
- Provide request counts and sums for free
- Enable exact threshold counts when edges are well placed
Disadvantages / Trade-offs
- Heavier than counters and gauges, especially with many attributes
- Percentiles are estimates, with accuracy limited by bucket width
- Explicit histograms need careful edge choices
- Exponential histograms are not supported everywhere yet
- Exact individual values are lost for good
Choosing between summaries
| Approach | What It Keeps | Can Combine Across Instances? | Best For |
|---|---|---|---|
| Average only | Sum and count | Yes, by adding sum and count | Rough trends where outliers do not matter |
| Precomputed percentile | One chosen percentile | No | Single-instance quick looks |
| Histogram | Counts per range | Yes, by adding bucket counts | Distributed services, goals and alerts |
| Raw values | Every measurement | Yes, but at huge cost | Small data sets and deep investigations |
“A histogram stores every value, so it is as accurate as the raw data.” It does not. A histogram stores counts per range, which is the reason it is small, and the reason percentiles drawn from it are estimates.
20Real-World Scenarios
Picture how different teams use histograms every day.
An online shop finds a hidden slow group
A dashboard showed an average checkout time of 800 milliseconds, which looked healthy. A histogram revealed that one request in twenty took over six seconds. Tracing those slow requests through exemplars led to one overloaded payment region. Fixing it removed hundreds of abandoned carts a day.
A streaming service tunes its bucket edges
A team noticed that percentile charts for video start-up time looked jagged. They found that most measurements fell between two widely spaced edges. After adding edges at half-second steps in that range, the charts became smooth and the alert thresholds became accurate.
A bank promises a response time
The bank promised that 99 percent of transfers would finish within two seconds. By placing a bucket edge at exactly two seconds, the team tracked the true fraction under that line and used the remainder as an error budget to decide when to slow down new releases.
A message platform watches payload sizes
A histogram of message sizes showed a growing tail of very large messages. The team discovered one client sending huge attachments by mistake. They added a size limit and the memory spikes on their servers disappeared.
A platform team reduces monitoring costs
A monitoring bill jumped after a new release. The team found that a duration histogram had gained a request identifier as an attribute. They removed the attribute using a view, and the costs dropped back immediately without any code change.
21Getting Started: A Gentle Path
You do not need to learn everything at once.
Pick one measurement that matters
Start with the duration of your most important request type, such as checkout or sign-in.
Turn on automatic instrumentation
Many libraries already produce a duration histogram following the standard conventions.
Send the data to a Collector and a viewer
Use a free open-source tool or your existing vendor, and confirm that histogram data arrives.
Check the buckets
Look at the counts per bucket. If most data sits in one bucket, adjust the edges with a view or try exponential histograms.
Chart the median and a high percentile
Show the 50th and 95th percentiles side by side. Compare them with the average to see how misleading the average was.
Add a goal, an alert and exemplars
Place an edge at your threshold, alert on the share of slow requests, and connect exemplars to traces for quick investigation.
Your first goal is not a perfect setup. It is to see the median and the 95th percentile side by side. The first time you notice how far apart they are, histograms will make complete sense.
22Frequently Asked Questions
It is an instrument that sorts many measurements, such as response times, into ranges called buckets and counts how many fell into each. It also keeps the total count and sum, so it preserves the shape of your data in a very small package.
Because averages hide outliers. A few very slow requests barely move the average, yet they are the ones that frustrate users. A histogram shows how many measurements were slow, so those problems become visible.
A bucket is a range of values with a lower and upper edge. Each measurement goes into the bucket whose range contains it, and only the bucket’s count is kept. There is always an extra overflow bucket for values above the largest edge.
The tool adds up bucket counts from the smallest bucket upwards until it reaches the desired share of the total, then estimates a position inside that bucket. The answer is therefore an estimate, and it is more accurate when buckets are narrow.
No. Percentiles cannot be averaged meaningfully. Instead, add the bucket counts of all servers together and estimate the percentile from the combined histogram.
In an explicit histogram, you choose the bucket edges in advance. In an exponential histogram, the edges follow a growth rule and adjust automatically to your data. Exponential histograms need little tuning, but not every backend supports them yet.
The most likely cause is a mismatch between your unit and your bucket edges, for example recording seconds with edges designed for milliseconds. Adjust the edges using a view, or switch to exponential histograms.
The OpenTelemetry semantic conventions recommend seconds, written as decimal numbers. Whatever unit you choose, set it clearly on the metric and make sure your bucket edges match.
A histogram stores a number per bucket plus a count and a sum for each combination of attributes, while a counter stores one. More buckets and more attribute combinations multiply the storage and query cost.
An exemplar is a small sample attached to a histogram bucket that records a real measurement together with its trace identifier. It lets you jump from a slow bucket straight to the trace of an actual slow request.
Yes. Views are configuration rules that can change bucket edges, switch the histogram type, remove attributes, or rename and drop metrics, all without editing the code that records the measurements.
No. Use histograms for the measurements where the spread truly matters, such as user-facing request times. For minor or secondary measurements, a simple counter or gauge may be enough and is cheaper to store.
23Summary and Key Takeaways
A histogram in OpenTelemetry is the instrument that keeps the shape of your measurements. Instead of remembering every value, it sorts each one into a bucket and keeps the count per bucket along with the total count and the sum. That small table lets you estimate percentiles, compute averages and rates, check goals at exact thresholds, and combine data from many instances correctly by adding bucket counts. Explicit histograms use edges that you choose, so the edges must match your unit and your range of values. Exponential histograms choose their own edges and adapt automatically, as long as your backend supports them. Views let you tune histograms without touching code, exemplars connect buckets to real traces, and careful control of attributes keeps costs under control. Used well, histograms reveal the unhappy few that averages hide.
Key Takeaways
- Histograms keep the shape of the data — they sort measurements into buckets and store counts, so you see the spread instead of one misleading average.
- Each data point is a small bundle — bucket counts, bucket edges, a total count, a sum and optionally minimum and maximum, plus attributes and timestamps.
- Percentiles are estimates — they come from bucket counts, so narrower buckets near the percentile give better accuracy.
- Histograms can be added together — combine bucket counts across instances first, then estimate percentiles, and never average percentiles.
- Match edges to your unit — default edges can ruin a seconds-based histogram, so tune them with views or use exponential histograms where supported.
- Mind the cost — every bucket is stored for every attribute combination, so keep attributes small and bounded and avoid unique identifiers.
- Connect and act — place edges at your goal thresholds, alert on the share of slow requests, and use exemplars to jump from a slow bucket to a real trace.