What Is a Gauge in OpenTelemetry?
A plain-English guide to the metric that answers one simple question: "What is the value right now?" You will learn how it works, when to choose it, and the mistakes that make gauge charts lie.
Look at the dashboard of a car. You will see a speedometer, a fuel gauge, and an engine temperature needle. None of these tells you how many miles you have driven in total, or how many times you pressed the brake. They tell you something much simpler: what the value is at this very moment. The needle can rise, and it can fall. If you look away and look back, it may be somewhere else.
Software needs the same kind of needle. How much memory is the program using right now? How warm is the server room? What percentage of the CPU is busy? How full is the disk? In OpenTelemetry, the tool for this kind of question is called a gauge.
In this guide, you will learn what a gauge is, how it differs from the other metric types, how it is created and collected, how the SDK handles it inside, and how to avoid the classic traps. No prior knowledge is needed. Every new word is explained the first time it appears.
1What Is a Gauge?
A gauge is a metric that reports the current value of something that can go up and down. It is a snapshot, not a running total.
First, what is a metric?
A metric is a number that is measured over time, such as “requests per second” or “memory in use”. Unlike a log, which tells a story in words, or a trace, which follows one request, a metric squeezes a lot of activity into a small number. That makes it cheap to store and perfect for charts and alerts.
Now, the gauge
A gauge is the metric type for a value that is a level, not a count of events. Think of a thermometer. It does not add up all the heat it has ever felt. It simply shows the temperature now. In OpenTelemetry, a gauge records a measurement such as “the temperature is 21.5 degrees” or “CPU is 63 percent busy”, and the system sends that number onward, together with the time it was taken and a few labels that say what it describes.
One property is the heart of the gauge idea: its values are non-additive. This means that adding two readings together does not make sense. If two rooms are each 21 degrees, the combined temperature is not 42 degrees. If you remember only one thing from this guide, remember this: use a gauge when summing the values would be meaningless.
A bathroom scale is a gauge. Each time you step on it, it shows your weight at that moment. It does not remember what you weighed last week, and it does not add today’s weight to yesterday’s. If you want a story over time, you write the numbers down on a chart. A gauge gives you the numbers. The chart tells you the story.
Where the gauge lives
Like every OpenTelemetry metric, a gauge is created through the SDK. Your code asks a meter to create an instrument. The instrument is the object you use to report numbers. The SDK then collects those numbers on a schedule and sends them to a backend, a program that stores them and draws charts. You will see each of these steps in detail in the chapters ahead.
A quick test: ask “If I had this reading from ten machines, would adding them together make sense?” If the answer is no, such as with temperature or a percentage, you probably want a gauge.
2The Family of Instruments
The gauge is one member of a small family of metric instruments. Seeing the whole family makes it much easier to know when to pick the gauge and when to pick something else.
The instruments at a glance
OpenTelemetry offers a few instrument types, and each one fits a different shape of data. Most of them come in two styles. A synchronous instrument is one you call from your own code at the moment something happens. An asynchronous (or observable) instrument is one where you register a small function, called a callback, and the SDK calls it when it is time to collect.
| Instrument | Style | Question it answers | Example |
|---|---|---|---|
| Counter | Synchronous | How many times did it happen? | Orders placed |
| Observable Counter | Observable | What is the running total, read when asked? | Total bytes read from a disk |
| UpDownCounter | Synchronous | What is the total, when changes can go either way? | Active requests |
| Observable UpDownCounter | Observable | The same, read when asked | Items in a queue |
| Histogram | Synchronous | How are the values spread out? | Request duration |
| Gauge | Synchronous | What is the current value? | Current room temperature, set when it changes |
| Observable Gauge | Observable | What is the current value, read when asked? | CPU utilization |
A decision path
The diagram below turns the table into a path you can follow with a few yes-or-no questions.
flowchart TB
Q["What are you measuring?"] --> A{"Counting events that only go up?"}
A -- Yes --> C["Counter"]
A -- No --> B{"A level that moves up and down, and adding readings makes sense?"}
B -- Yes --> U["UpDownCounter"]
B -- No --> D{"Do you need the spread of many values?"}
D -- Yes --> H["Histogram"]
D -- No --> G["Gauge (current value, adding makes no sense)"]
Start at the top. If you are counting things that happen, such as orders or errors, use a counter. If you track a quantity that rises and falls but where totals still make sense, such as the number of items waiting in a queue, use an up-down counter. If you care about the shape of many measurements, such as how long requests took, use a histogram. Everything left over, the levels and readings where adding is meaningless, belongs to the gauge.
The synchronous gauge is a newer addition to the OpenTelemetry metrics API. For a long time, the observable gauge was the only gauge. Support for the synchronous version differs by language and version, so check the documentation of the SDK you use.
3Gauge vs Counter vs UpDownCounter vs Histogram
Beginners most often mix up the gauge and the up-down counter, and sometimes the gauge and the histogram. Let us separate them carefully.
Gauge or counter?
A counter only goes up. It counts things that happened, such as page views. If you restart the program, it starts again at zero. Its most useful question is “how fast is it growing?”, which is a rate. A gauge is not about growth. It is about the level. Asking for the “rate of a temperature” almost never makes sense, while asking for the “rate of orders” always does.
Gauge or up-down counter?
This is the subtle one. Both can rise and fall. The difference is whether adding makes sense. The number of items in a queue on server A and on server B can be added to give the total waiting. That is additive, so an up-down counter fits. The CPU utilization of server A and server B cannot be added into anything useful. That is non-additive, so a gauge fits. In OpenTelemetry’s standard naming rules, system memory usage in bytes is modeled with an up-down counter because the sum across machines is meaningful, while CPU utilization is modeled as a gauge.
Gauge or histogram?
A gauge keeps only the latest value. A histogram keeps the spread of every value it saw, sorted into buckets. If you record request durations in a gauge, you see only the last request, and everything before it is lost. If you record them in a histogram, you can find the median and the 99th percentile. Use the gauge for a state, and the histogram for a distribution of events.
| Feature | Gauge | Counter | UpDownCounter | Histogram |
|---|---|---|---|---|
| Goes down? | Yes | No | Yes | Not applicable |
| Adding readings makes sense? | No | Yes | Yes | Merges into buckets |
| What is kept? | Latest value | Running total | Running total | Count, sum, and bucket spread |
| Typical question | What is it now? | How many, how fast? | How many right now? | How slow was the slowest few percent? |
| Example | CPU utilization | Orders placed | Active connections | Request duration |
Picture a car again. The odometer, which only goes up, is a counter. The number of passengers currently in the car, which goes up and down and can be added across cars, is an up-down counter. The engine temperature needle is a gauge. A log of every speed you drove at each minute, sorted into “slow, medium, fast”, is a histogram.
Do not use a gauge to count events by writing “current total” into it. You lose the ability to compute reliable rates and you create gaps when the program restarts. Use a counter for anything that counts.
4Two Ways to Report: Synchronous and Observable Gauges
You can feed a gauge in two different ways. Choosing the right one is mostly about who knows when the value changes.
The synchronous gauge: you push when it changes
With a synchronous gauge, your own code calls a record function whenever the value changes. Imagine a smart thermostat that reacts to a new temperature reading and immediately tells the gauge, “it is now 22.1”. The SDK remembers the most recent value for each set of labels. When the time comes to export, it sends the latest one. This style fits cases where your code already knows the moment of change, such as a setting a user just changed.
The observable gauge: the SDK asks when it needs to know
With an observable gauge, you give the SDK a small function called a callback when the instrument is created. During every collection cycle, the SDK calls the callback, and the callback reads the current value from wherever it lives, such as the operating system, a sensor, or a pool of connections, and returns it. Nobody has to call anything when the value changes. The SDK checks only when it plans to export. This style fits things that exist independently of your code, such as CPU load or free disk space.
sequenceDiagram
participant App as Application Code
participant SG as Synchronous Gauge
participant OG as Observable Gauge
participant R as Metric Reader
participant Sys as Sensor or System
App->>SG: record 22.1 when the value changes
Note over SG: SDK keeps only the latest value
R->>SG: Collect (on a timer)
SG-->>R: Latest recorded value
R->>OG: Collect (on a timer)
OG->>Sys: Callback reads current value
Sys-->>OG: 63 percent
OG-->>R: Observation 63
| Question | Synchronous gauge | Observable gauge |
|---|---|---|
| Who starts the reading? | Your code | The SDK, through your callback |
| When is the value read? | When the value changes | At every collection cycle |
| Good for | Values your code sets, such as a configured limit or a current mode | Values owned by the system, such as CPU, memory ratios, and temperatures |
| Risk | If you stop calling record, an old value may keep being reported | A slow callback delays collection |
| Maturity | Newer, support varies by language | Older and widely available |
A synchronous gauge is like a friend who texts you each time the weather changes: “now it is raining”. An observable gauge is like you looking out of the window whenever you plan to leave the house. Both tell you the weather. The first is driven by the event, and the second is driven by your schedule.
When in doubt, choose the observable gauge for anything that already lives somewhere you can read at any time. It keeps reading code in one place and ties the reading to the collection schedule.
5The Anatomy of a Gauge Measurement
What does a gauge actually carry? Let us open one up and look at each part.
Name
A dotted, lowercase name that says what is measured, such as a name for CPU utilization. Use the standard names from the semantic conventions when one exists.
Description
A short sentence for humans, explaining what the number means. It shows up in tools and saves guesswork later.
Unit
What the number is measured in, such as seconds, bytes, degrees Celsius, or a plain ratio. Without a unit, numbers are ambiguous.
The number
Either a whole number or a decimal number. The choice is made when you create the instrument.
Attributes
Key and value pairs such as the room name or the disk name. Each different set of attributes creates its own separate series of readings.
Timestamp
The moment the value was taken. Charts use it to draw the line over time.
Resource
Facts about the producer: service name, version, host, and so on. The resource is attached once and applies to all signals from that service.
Instrumentation scope
The name of the library or module that created the metric, so you can tell whose gauge you are looking at.
The data point in the wire format
When the SDK sends a gauge through OTLP, the OpenTelemetry wire format, the metric arrives as a record of type “gauge”, containing a list of data points. Each data point holds the number, the timestamp, and the attributes. Notice what is missing. A gauge data point has no “temporality” and no “monotonic” flag, which belong to counters and similar types. A gauge simply says: “at this time, for these labels, the value was this”.
Think of a weather station’s log entry: “Station 14, north roof, at 10:05, temperature 21.5 degrees Celsius”. The station is the resource, “north roof” is an attribute, 10:05 is the timestamp, and 21.5 with its unit is the value. A gauge data point is exactly such a log entry.
Because one gauge instrument can have many attribute combinations, one instrument can produce many data points per collection cycle, one for each combination you reported.
6What to Measure with a Gauge, and What Not To
The gauge is simple, but choosing the right things to put in it is a skill. Here are good fits, and some tempting wrong fits.
Good fits
CPU or disk utilization
A percentage-style value between zero and one. Averaging across machines makes sense, adding does not.
Temperature and humidity
Real-world sensor readings. They go up and down and can never be added into a total.
Configured limits
The current maximum pool size, a feature flag percentage, or a rate limit. They change rarely, and the latest value is what matters.
Replication lag or queue age
How far behind something is right now. A level that shows how healthy a pipeline is.
Fill levels
The fraction of a buffer or a connection pool that is used, expressed as a ratio.
Mode or status values
A number that stands for a state, such as 1 for “primary” and 0 for “replica”. Use sparingly and document the meaning.
Tempting wrong fits
| Tempting idea | Why it is wrong | Better choice |
|---|---|---|
| Total requests served so far | It is a count of events that only grows | Counter |
| Request duration | Only the last duration would survive | Histogram |
| Items waiting in a queue across many servers | You will want to add them, which a gauge discourages | UpDownCounter |
| Number of errors per minute | It is a rate derived from a count | Counter, then compute the rate |
| Each user’s last login time | Unbounded labels, with a value that is not a level | Logs or a database |
Write down the sentence a person would say when reading the chart, for example “CPU is at 63 percent”. If the sentence sounds like “it is currently …”, you probably have a gauge.
7How the SDK Handles a Gauge Internally
Let us follow one gauge reading from your code to the network. Knowing these steps explains almost every surprising thing you might see on a chart.
Startup configuration
The program creates a MeterProvider with a resource, a metric reader, and an exporter, and registers it. Nothing is measured yet.
Create the meter and the gauge
Code asks the provider for a meter, then asks the meter for a gauge with a name, a unit, and a description. For an observable gauge, it also hands over a callback.
A measurement is made
For a synchronous gauge, your code records a value together with its attributes. For an observable gauge, the SDK will get its measurements later through the callback.
Views are applied
If a view is configured, it may rename the metric, limit its attributes, or change its aggregation. Without views, defaults apply.
The “last value” aggregation
The SDK keeps one value per set of attributes. A new measurement with the same attributes replaces the old one. Only the latest value survives.
The reader collects
On a timer, with a default of about one minute, the metric reader asks the SDK for everything. Observable callbacks run now, and the stored last values are gathered.
Export
The exporter converts the collected values into OTLP gauge data points and sends them to the Collector or backend, retrying on temporary failures.
The big consequence: values between collections are lost
Because the gauge keeps only the last value, anything that happens between two collections and is then replaced never leaves the program. If CPU jumps to 99 percent for five seconds and falls back to 40 percent before the next collection, the gauge reports 40. The spike is invisible. This is not a bug. It is how a gauge is defined: “the value at the moment of reading”.
A security guard walks past a door once every ten minutes and writes down whether it is open or closed. If the door was opened and closed again between two walks, the guard’s notebook never shows it. The notebook is accurate about the moments it records, and silent about everything between them.
If catching short peaks matters, such as brief CPU spikes or the highest queue age, do not rely on a gauge alone. Record the maximum separately, or use a histogram of the value, so that peaks cannot slip between collections.
8Callbacks in Depth: The Life of an Observable Gauge
The callback is the single most important part of an observable gauge, and the place where most bugs hide. Let us watch one in action.
sequenceDiagram
participant T as Timer (every 60 seconds)
participant R as Periodic Metric Reader
participant S as SDK
participant CB as Your Callback
participant OS as Operating System
participant E as OTLP Exporter
T->>R: Time to collect
R->>S: Collect all instruments
S->>CB: Invoke callback
CB->>OS: Read CPU utilization
OS-->>CB: 0.63
CB-->>S: Observation 0.63 with attributes
S-->>R: Metric data with gauge data points
R->>E: Export batch
Read the figure from top to bottom. A timer fires. The reader asks the SDK to collect. The SDK runs your callback, the callback reads the real value, and returns an observation, which is a value plus its attributes. The SDK packages everything into metric data, and the reader hands it to the exporter. The whole cycle repeats at every interval.
Rules for writing a good callback
Be fast
The callback runs inside the collection step. A callback that takes seconds delays every other metric and may be cut off by a timeout.
Never block or wait
Do not wait on locks, slow network calls, or databases. Read cached values or fast local sources.
Do not change anything
A callback should only read. It should not write data, send messages, or reset counters, because it may run more than you expect.
Report current values only
Return what is true now. Do not return old cached numbers that could be hours stale without saying so.
Report every label set each time
If a disk exists, report it every cycle. Missing observations make the series look like it disappeared.
Handle errors quietly
If reading fails, skip the observation instead of crashing. A failed reading should not stop your application.
One callback, many readings
A single callback can return many observations, each with different attributes. For example, one callback can report the temperature of every room in a building, tagging each reading with the room name. Some SDKs also allow one callback to feed several instruments at once, which is useful when one system call returns several related numbers together.
If the real reading is expensive, such as a call to a remote service, update a cached value from a background task and let the callback only read that cache. This keeps collection fast and predictable.
9Aggregation, Temporality, and Views for Gauges
Three technical words, aggregation, temporality, and view, decide how measurements turn into exported metrics. For a gauge, the story is happily short.
Aggregation: last value wins
Aggregation is the way many measurements are combined into one number. For counters, the usual aggregation is a sum. For histograms, it is bucket counts. For a gauge, the default is the last value, which means that when several measurements arrive with the same attributes during one cycle, only the latest is kept. This matches the meaning of a gauge: the newest reading replaces the older one.
Temporality: not needed
Temporality describes whether exported numbers are running totals since start (cumulative) or changes since the last export (delta). It matters for counters and histograms. It does not matter for a gauge, because a gauge reports a level, and a level has no “total so far” or “change since last time”. This is one less thing to configure, and one reason gauges are friendly to many backends.
Views: powerful but handle with care
A view is a rule you set in the SDK to reshape a metric before it is exported. It can rename the metric, filter its attributes, or choose another aggregation. With gauges, one use deserves a warning. If a view removes an attribute, then several series that were separate become one, and the gauge keeps only the last value among them.
| Topic | Counter | Histogram | Gauge |
|---|---|---|---|
| Default aggregation | Sum | Buckets | Last value |
| Temporality matters? | Yes | Yes | No |
| Removing an attribute merges series by | Adding them | Merging buckets | Keeping only the last one |
| Safe to merge across series? | Yes | Yes | Usually not |
Imagine three thermometers in three rooms. If you tell someone, “forget the room names and give me one temperature”, they will pick whichever thermometer they looked at last. That number is not the average, not the highest, and not the lowest. It is just the last one. A gauge with a removed attribute behaves the same way.
Prefer to keep all gauge attributes in the SDK and combine series later at query time, using average, maximum, or minimum, whichever fits your question. Merging inside the SDK by dropping attributes quietly discards information.
10Data Flow and Lifecycle: From Gauge to Dashboard
The SDK is only the start of the journey. Where does a gauge reading go after it leaves your program, and what happens to it there?
flowchart LR
I["Gauge instrument in your code"] --> M["Measurement"]
M --> V["View (optional)"]
V --> AG["Last value aggregation"]
AG --> MR["Periodic Metric Reader"]
MR --> ME["OTLP Metric Exporter"]
ME --> CO["Collector (agent or gateway)"]
CO --> BE["Metrics Backend"]
BE --> DB["Dashboards and Alerts"]
The stages of life
Produce
Your code records a value, or the SDK reads one through a callback.
Shape
The SDK applies views, keeps the last value for each attribute set, and attaches the resource.
Ship
The reader collects on its timer and the exporter sends OTLP data, usually to a nearby Collector.
Route
The Collector can batch, filter, rename, or add labels, then forward the data to one or more backends.
Store and query
The backend stores a line of values over time for each label set, and lets people chart and alert on them.
Expire
Old data is deleted according to a retention rule. A series that stops receiving data is marked stale.
How backends treat a gauge
Many backends have a gauge idea of their own. In Prometheus-style systems, an OpenTelemetry gauge becomes a Prometheus gauge, a value that can go up or down. In query languages, you chart gauges directly, or use functions such as average, minimum, and maximum over a time window. You would almost never take the “rate” of a gauge, since a rate is meant for things that only grow.
The Collector can sit in the middle and change gauge data on the way, for example by dropping noisy labels or renaming metrics. Treat such changes as part of your design, because they affect what the chart finally shows.
11Gauges Across Many Instances
In production you rarely have one copy of a service. You have dozens. How do gauges behave when many copies report the same metric?
flowchart LR
P1["Pod 1 (gauge: cpu utilization 0.40)"] --> CO["Collector"]
P2["Pod 2 (gauge: cpu utilization 0.85)"] --> CO
P3["Pod 3 (gauge: cpu utilization 0.55)"] --> CO
CO --> BE["Backend stores three separate series"]
BE --> Q["Query: average or maximum, never the sum"]
Each copy needs its own identity
The resource attached to each copy should contain an attribute that tells the copies apart, such as a service instance ID. Without it, three gauges with identical labels would collide in the backend, and they would overwrite each other. You would see a jittery line, jumping among the three values, that tells the truth about none of them.
Combine them at query time
Once the backend holds one series per copy, you decide how to combine them for the question at hand. To ask “is any copy overloaded?”, use the maximum. To ask “how busy is the fleet in general?”, use the average. To ask “which copy is the problem?”, look at each series on its own. The sum of CPU utilization percentages across copies is rarely useful, since it does not describe any real thing.
| Question | Combine with |
|---|---|
| Is any copy in trouble? | Maximum |
| How is the fleet doing overall? | Average |
| Is any copy idle and wasting money? | Minimum |
| Which exact copy is the problem? | No combination, view each series |
A school has thirty classrooms, each with a thermostat. The principal asks, “Is any room too hot?” and the caretaker answers with the highest temperature. Nobody asks for the sum of all the thermostat readings, because a number like 630 degrees describes nothing.
12Attributes and Cardinality for Gauges
Attributes make a gauge useful, and they are also the fastest way to make it expensive. The word to know is cardinality.
What is cardinality?
Cardinality is the number of different attribute combinations a metric has. A gauge for room temperature with a “room” attribute and thirty rooms has a cardinality of thirty. Each combination becomes its own series in the backend, with its own storage and indexing cost. Cardinality is the main cost driver of metrics.
| Attribute | Possible values | Verdict |
|---|---|---|
| Room name | Dozens | Good |
| Disk device name | A handful per machine | Good |
| Region | A few dozen | Good |
| User ID | Millions | Bad |
| Full URL with parameters | Practically unlimited | Bad |
| Request ID | Unlimited | Never |
If a school puts one thermometer in every classroom, the caretaker has thirty readings to watch. If someone attached a thermometer to every student’s shirt, the caretaker would have a thousand readings, most of them useless. Attributes decide how many thermometers you hire.
Rules of thumb
- Use attributes that have a small, known set of values.
- Never use values that grow with traffic, such as user IDs, session IDs, or full URLs.
- Prefer stable names, such as the route template “orders by ID”, over actual paths.
- Remember that each attribute multiplies the others. Ten rooms times ten devices times five regions already makes five hundred series.
A gauge with unlimited attribute values keeps creating new series, and old ones keep sitting in storage. Newer SDKs include a limit on series per metric, and extra series are folded into an overflow bucket, but the safe path is to design your labels well from the start.
13Units and Naming: Making Numbers Mean Something
A gauge that says “42” is almost useless. Forty-two what? Names and units turn a bare number into information.
Always set a unit
The unit says what the number is measured in. OpenTelemetry follows a standard code system for units, so values like seconds, bytes, and degrees Celsius have agreed short codes. For plain ratios, such as “CPU is 63 percent busy”, the convention is to report a fraction between zero and one, for example 0.63, with the unit “1”, instead of a number between zero and one hundred. Charts and tools can then show it as a percentage, and mixing up scales becomes less likely.
Names tell the story
A good metric name is lowercase, uses dots to separate parts, and reads like a short description of the thing: the area first, then the quantity. The semantic conventions already define names for common things such as CPU, memory, disk, and network. If one fits, use it, because dashboards and alerts written by other people will understand your data right away.
| Do | Do not |
|---|---|
| Use a standard name when one exists | Invent a new name for CPU utilization |
| Put the unit in the unit field | Put the unit inside the name, like “temperature in celsius” |
| Report ratios as zero to one | Report some services as 0 to 1 and others as 0 to 100 |
| Keep the same name and unit forever | Change the unit later without telling anyone |
| Add a clear one-line description | Leave the description empty |
A recipe that says “add 2 of sugar” is a problem. Two spoons, two cups, or two kilograms? A unit prevents a kitchen disaster, and in monitoring it prevents a dashboard disaster.
Decide the value type, whole number or decimal, when you create the instrument. Temperatures and ratios need decimals, while counts of things like connections fit whole numbers.
14A Worked Example: What the Gauge Reports, and What It Misses
Let us run a small experiment on paper. A service has an observable gauge for CPU utilization, and the SDK collects once per minute.
What really happened inside one minute
Imagine that, during one minute, the real CPU load changed like this, measured every ten seconds. These are the true values, which the gauge cannot see.
| Second | True CPU utilization | Seen by the gauge? |
|---|---|---|
| 0 to 10 | 40 percent | No |
| 10 to 20 | 42 percent | No |
| 20 to 30 | 95 percent | No |
| 30 to 40 | 97 percent | No |
| 40 to 50 | 41 percent | No |
| 50 to 60 | 40 percent | Yes, read at second 60 |
What the gauge reports
At second 60, the SDK runs the callback, and the callback returns the current value, about 40 percent. That is the only number exported for this minute. The chart will show a calm 40 percent line, and nobody will ever know that for twenty seconds the machine was almost fully busy.
Compare this with the real picture. The average over the minute was about 59 percent (the six values add up to 355, and 355 divided by 6 is about 59). The maximum was 97 percent. The gauge told the truth about one instant and said nothing about the rest.
Three ways to see more
Collect more often
A shorter interval, such as every 10 seconds, would catch this spike. It also multiplies data volume by six, so use it only for metrics that earn it.
Report the window’s maximum
Keep track of the highest value inside your program and report it as a second gauge, with a name that says it is a maximum over the last window.
Use a histogram
Record each sample into a histogram. You then see how the values were spread, including the high ones, and can compute high percentiles.
Let the system average it
Many systems already expose an average over a window, such as a load average. Observe that value with the gauge instead of the raw instant.
A teacher checks the playground once every hour and writes “quiet”. She is right every time she looks, yet she completely misses the argument that happened between her visits. To learn about arguments, she would need to visit more often, ask the children to report them, or keep a diary of incidents.
A flat gauge chart does not prove that nothing happened between samples. It proves only that the sampled moments looked flat.
15Monitoring, Logging, and Alerting with Gauges
Gauges are the natural fuel for dashboards and alerts about health and capacity. A few habits make those alerts calm instead of noisy.
flowchart LR
G["Gauge: disk fullness ratio"] --> BE["Metrics Backend"]
BE --> RU{"Rule: above 0.9 for 10 minutes?"}
RU -- No --> OK["No alert"]
RU -- Yes --> AL["Alert sent to on-call engineer"]
AL --> IN["Engineer opens dashboard, logs, and traces"]
Good alert habits
- Use a duration. Alert when the value stays above a limit for several minutes, not on a single reading. This avoids waking someone for a harmless blip.
- Pick the right combination. For fleets, alert on the maximum if one bad copy matters, or on the average if only a general problem matters.
- Alert on missing data too. If a gauge stops reporting, the chart simply ends. Add a rule that fires when expected data is absent.
- Watch trends, not only levels. A disk that fills by two percent per hour will be full in a day, even though it is fine now. Use a prediction function for such cases.
- Add context to the alert. Include the service name, instance, and a link to the right dashboard.
Connecting gauges to the other signals
A gauge tells you that something is off. Traces and logs help you find out why. They are connected through shared resource attributes, such as the service name and instance ID, and through time. When a CPU gauge climbs at 10:05, you can open traces and logs from the same service and instance around 10:05 to see what the code was doing. Gauges do not carry trace IDs on their values, so the link is made by labels and time.
Treat a gauge as a smoke detector, not a fire investigator. It is excellent at saying “look here, now”. The detailed cause usually lives in traces and logs.
16Security: Gauges Reveal More Than You Think
A single number looks harmless, yet a collection of gauges describes the health, size, and habits of your systems. Protect it accordingly.
Business facts in numbers
A gauge for active users, balances, or stock levels can reveal sensitive business information. Limit who can read such metrics.
Risky attribute values
Hostnames, IP addresses, customer names, and file paths used as attributes reveal the layout of your systems. Keep labels generic.
Encrypt the pipe
Send OTLP over an encrypted connection between SDKs, Collectors, and backends, so readings cannot be read or changed on the way.
Authenticate the receiver
An open Collector can be fed false readings that trigger alerts or hide real problems. Require tokens or certificates.
Untrusted values
If a gauge is set from user input, an attacker can write any number they like, or create unlimited labels. Validate and cap what you accept.
Callbacks run with your privileges
A callback reads from the system with the same power as your application. Keep it small, reviewed, and limited to the sources it needs.
A protective checklist
- Review every attribute and ask whether it is safe to show to everyone who can see dashboards.
- Scrub or drop sensitive labels in the Collector before data reaches storage.
- Separate production and test metrics so test values cannot trigger production alerts.
- Control who can edit alert rules, since changing a threshold can silence an alarm.
Never build a gauge label from raw user input without limits. It is both a security risk and a quick path to a huge bill.
17Performance and Reliability
Gauges are among the cheapest signals you can produce, but a few details can still hurt, and some failure behaviors are surprising.
What costs time and memory
The callback itself
A callback that reads many files or sensors on every cycle adds work. Keep reads small and cache what is slow.
One slot per label set
The SDK keeps the latest value for each attribute combination. A thousand combinations means a thousand slots, which is fine. A million is not.
Interval and series count
Data sent equals series multiplied by how often you collect. Doubling either one doubles the traffic.
Many threads recording
If many threads record to the same synchronous gauge with the same labels, the last writer wins. This is safe but can produce confusing values.
Choosing the collection interval
The collection interval is a trade between detail and cost. A common default is about one minute, which suits slow-moving values like disk usage. Faster-changing values, like CPU on a busy machine, may justify ten to fifteen seconds. Slower interval means fewer points and bigger gaps. Faster interval means more detail and more cost. Pick based on how quickly the value can change and how quickly you need to react.
Gaps are permanent
Here is a reliability detail that surprises many people. A cumulative counter heals itself: if one export is lost, the next one still holds the full running total, so the chart recovers. A gauge cannot heal. If an export is lost because the Collector was down, the readings for that interval are simply gone, since they were instants in time. Your charts will show gaps.
Run more than one Collector copy behind a load balancer, and keep the SDK’s export timeout short. This reduces the chance of long gaps when a single Collector restarts.
18Advantages, Disadvantages, and Trade-offs
The gauge is simple and honest, and its simplicity is both its strength and its limit.
Advantages
- Very easy to understand: it is the current value.
- Cheap to produce, store, and chart.
- No temporality settings to worry about.
- Fits levels and states that other instruments cannot represent.
- Maps cleanly to the gauge type of popular backends.
- Observable gauges keep reading code in one place, run on the collection schedule.
Disadvantages
- Misses anything that happens between collections.
- Lost readings cannot be recovered, only gaps remain.
- Merging series by dropping labels keeps only the last value, which is rarely meaningful.
- No built-in way to see highs, lows, or spread.
- Easy to misuse for counting, which makes rates impossible.
- Synchronous gauge support differs between languages and versions.
Choices to make on purpose
| Decision | Choose the first when | Choose the second when |
|---|---|---|
| Synchronous or observable gauge | Your code knows exactly when the value changes | The value lives in a system you can read at any time |
| Gauge or up-down counter | Adding readings is meaningless | Adding readings gives a true total |
| Gauge or histogram | You need the current state | You need highs, lows, and the spread |
| Short or long interval | Values change quickly and detail matters | Values change slowly and cost matters |
19Design Patterns and Anti-patterns
Teams who run metrics at scale tend to settle on the same few habits. Here they are, along with the traps that keep catching newcomers.
Patterns worth copying
Observe, do not push, system values
For CPU, memory ratios, and temperatures, use an observable gauge with a small, fast callback.
Ratio from zero to one
Report utilization as a fraction with the unit “1”, so every service speaks the same scale.
Gauge plus histogram together
Report the current value with a gauge and the shape of samples with a histogram, so you get both state and spikes.
Cache expensive reads
A background task refreshes slow readings. The callback only returns the cached number.
Unique instance identity
Every copy of a service sets a service instance ID, so gauge series never collide.
Combine at query time
Keep detailed labels in the SDK and let the backend compute average, maximum, or minimum when you need them.
Anti-patterns to avoid
The Mistake
Using a gauge as a hand-made counter, for example by storing “total orders so far” in a gauge.
Why It Hurts
Restarts reset the number, rates become unreliable, and every consumer has to guess what the value means.
Do This Instead
Use a counter for totals. Let the backend compute the rate from the counter.
The Mistake
Writing a callback that makes a slow network call or database query on every collection cycle.
Why It Hurts
Collection becomes slow, other metrics are delayed, and a failing dependency can freeze your monitoring when you need it most.
Do This Instead
Refresh the reading in a background task and let the callback return the cached value.
The Mistake
Summing gauge series from many instances to get a “total”, such as adding up CPU percentages.
Why It Hurts
The result describes nothing real and hides which copy is in trouble. Dashboards based on it mislead people.
Do This Instead
Use maximum, average, or minimum across copies, or an up-down counter if the quantity really is additive.
20Best Practices and Common Mistakes
Keep this short list close. It prevents most of the trouble that beginners meet with gauges.
Ask the “adding” question first
If summing readings would make sense, use a counter or up-down counter. If not, use a gauge.
Set name, unit, and description
Follow the standard names where they exist, and report ratios as values from zero to one.
Keep callbacks fast and read-only
Read cached or local values. Never wait on slow dependencies inside a callback.
Limit attribute values
Use small, fixed sets of labels. Keep user IDs and URLs out of gauges.
Give every instance an identity
Set a service instance ID in the resource so series from different copies stay separate.
Choose the interval on purpose
Match it to how fast the value changes, and remember that spikes between samples are invisible.
Alert with windows and missing-data rules
Use a duration, pick maximum or average with intent, and alert when expected data stops arriving.
Common mistakes and their fixes
| Mistake | What you will see | Fix |
|---|---|---|
| Gauge used to count events | Rates that jump or drop at restarts | Switch to a counter |
| Same labels from many instances | A jittery line jumping between values | Add a service instance ID to the resource |
| Dropping labels in a view | A single series showing an arbitrary last value | Keep labels, combine at query time |
| Slow callback | Delayed or missing metrics, timeouts | Cache the reading, keep the callback tiny |
| Ratios on different scales | Charts that disagree between services | Use zero to one with unit “1” everywhere |
| Missing no-data alert | An outage that looks like a quiet day | Add a rule for absent data |
| Expecting to see spikes | A flat line during a real incident | Add a maximum gauge or a histogram |
21Real-World and Industry Examples
First, a made-up story that shows gauges at work. Then, a look at where gauges already show up across the industry.
An illustrative story: the greenhouse that was always too warm
Imagine a company that runs forty greenhouses, each with several temperature sensors. A small service reads the sensors and reports an observable gauge called temperature, with attributes for the greenhouse and the zone. The dashboard shows each greenhouse as a line, and an alert fires when the maximum zone temperature stays above 30 degrees Celsius for ten minutes. One week, greenhouse 17 triggers the alert every afternoon. The team opens its series and sees that zone C climbs steadily from noon, while zones A and B stay normal. The cause turns out to be a stuck window vent in that zone. Because the gauge carried the zone label, the problem was located in minutes. Had they summed the temperatures or removed the zone label, the issue would have been hidden. (This is a made-up example to show the workflow, not a report from a real company.)
Host and container metrics in the Collector
The OpenTelemetry Collector includes receivers that read host and container statistics, such as CPU, memory, and disk. Many of the values they produce, utilization ratios in particular, are gauges, and they are a common first source of metrics for a new deployment.
Prometheus and StatsD: the older cousins
Prometheus and StatsD both have a gauge type with the same meaning, a value that can go up and down. OpenTelemetry’s gauge was designed to fit well with them, which is why gauge data moves between these systems with little friction.
Cloud monitoring services
Cloud platforms publish gauge-like readings for the resources they run, such as the CPU utilization of a virtual machine. Teams then compare these platform readings with gauges reported from inside their own applications to see both the outside and inside view of the same machine.
Runtime and application internals
Language runtimes can report things like the number of active threads or the size of memory pools. Depending on whether adding makes sense, these are modeled as gauges or up-down counters, and the semantic conventions explain which one to use for each.
22The Gauge in the Data Model: OTLP and Prometheus Mapping
Your gauge will be translated at least twice on its way to a chart. Knowing what each translation does helps you understand odd-looking results.
The OTLP shape
In OTLP, the standard wire format, a metric is one of several data types: sum, gauge, histogram, exponential histogram, or summary. A gauge metric holds a list of data points. Every data point has a number (whole or decimal), a time, and a set of attributes. It has no running-total flag and no aggregation temporality, because neither idea applies to a level.
A close cousin: the non-monotonic sum
An up-down counter does not travel as a gauge. It travels as a sum that is marked as not “monotonic”, which means it is allowed to decrease. That difference matters at the other end. A backend that sees a sum knows adding is allowed. A backend that sees a gauge knows it is not. Your choice of instrument therefore sends a message to every later system about how the numbers may be combined.
How the pieces map to Prometheus
| OpenTelemetry idea | What travels in OTLP | How a Prometheus-style backend sees it |
|---|---|---|
| Gauge or observable gauge | Gauge data points | A gauge series |
| Up-down counter | A sum that is not monotonic | Usually shown as a gauge, since it can fall |
| Counter | A monotonic sum | A counter series |
| Attributes | Key and value pairs on each point | Labels on the series |
| Resource attributes | Attached to the whole metric group | Often merged into one info series or copied as labels, depending on settings |
| Unit | A unit code on the metric | May be added as a suffix in the metric name |
Names can change in translation. Dots in OpenTelemetry names are turned into underscores, and some systems add suffixes for units. If you search for your metric and cannot find it, try the translated name first.
A letter written in English and delivered through a translator keeps its meaning, but some words come out slightly different. You would not panic if “colour” came back as “color”. Metric names going through a translation layer behave in the same way.
Rules for translating between OpenTelemetry and Prometheus have been refined over time, and options differ between Collector versions. Read the settings of the exporter you use, and test with one metric before rolling out widely.
23A Gauge Cookbook: Everyday Examples and How to Model Them
Here are common things teams want to measure, with a sensible way to model each. Use it as a starting point whenever you are unsure.
| What you want to know | Instrument | Unit | Useful attributes | How to combine across copies |
|---|---|---|---|---|
| How busy is the processor? | Observable gauge | Ratio, unit 1 | CPU core, state | Maximum or average |
| How full is the disk? | Observable gauge | Ratio, unit 1 | Device, mount point | Maximum |
| How warm is the room? | Observable gauge | Degrees Celsius | Room, zone | Maximum and minimum |
| What is the current rate limit setting? | Synchronous gauge | Requests per second | Service, tier | Latest, or compare copies |
| How far behind is the replica? | Observable gauge | Seconds | Replica name | Maximum |
| How full is the connection pool? | Observable gauge | Ratio, unit 1 | Pool name | Maximum |
| How old is the oldest waiting message? | Observable gauge | Seconds | Queue name | Maximum |
| How many items are in the queue in total? | Up-down counter | Items | Queue name | Sum |
How to read the cookbook
Notice a pattern: the “combine” column almost always says maximum, minimum, or average for gauges, and sum only for the up-down counter at the end. That one pattern captures the heart of this whole guide. Gauges are levels you compare. Counters and up-down counters are quantities you add.
Name the question
Write the question in plain words, such as “how full is the disk right now?” The question picks the instrument.
Choose the style
If the system already holds the value, use an observable gauge. If your code sets it, use a synchronous gauge.
Set the unit and labels
Give the metric a unit, and choose a few labels with small value sets.
Plan the chart and the alert
Decide how you will combine copies, and what duration an alert needs before it fires.
Add a short note to your team’s metric catalog for each gauge: what it measures, its unit, its labels, and how to combine it. Future colleagues will thank you.
24Troubleshooting a Gauge That Looks Wrong
Sooner or later a chart will look strange. Work through the stages of the journey in order, and the cause usually appears quickly.
Walk the path from end to start
Check the chart itself
Is the time range right? Is the query combining series the way you meant? A chart that sums a gauge can look wrong even when the data is fine.
Check the backend
Does the series exist under a translated name? Are recent data points arriving, or has the series gone stale?
Check the Collector
Is it receiving the metric? Turn on a debug exporter to print what passes through, and look for rules that rename, filter, or drop it.
Check the SDK export
Use a console exporter in a test run to see the exact data points leaving the program, with their values, units, and attributes.
Check the callback or recording code
Is the callback registered? Does it return values? Does it handle errors? Is the synchronous gauge actually being recorded?
Symptoms and likely causes
| Symptom | Likely cause | What to try |
|---|---|---|
| No data at all | Exporter endpoint wrong, or SDK not registered before the gauge was created | Check the endpoint, and register providers first |
| A perfectly flat line | Callback returns a cached or constant value, or the value is recorded only once | Verify the callback reads fresh data |
| Values 100 times too big or small | Percentages reported as 0 to 100 while the chart expects 0 to 1 | Standardize on the zero to one ratio |
| A line jumping between values | Several instances sharing the same labels | Add a service instance ID |
| Regular gaps | Exports failing or callback timing out | Check Collector health and callback speed |
| Missing labels | A view or Collector rule removed them | Review views and processors |
| Series that never go away | High-cardinality labels creating new series | Remove or bucket the offending label |
When a faucet at the top floor gives no water, a plumber does not start by replacing the faucet. She checks the pipe to the floor, then the pump, then the main valve. Following the path in order finds the break faster than guessing.
Do not “fix” a strange gauge chart by changing the query to hide the problem. Find out whether the data or the question is wrong, since a hidden fault will come back at a worse moment.
25Frequently Asked Questions
Quick answers to the questions people ask most often about gauges.
26Summary and Key Takeaways
You started with a car dashboard needle. You now know how that simple idea is built into OpenTelemetry, and how to use it without being fooled.
Key Takeaways
- A gauge reports the current value of a level. It is non-additive, so use it when summing readings would be meaningless, such as temperature or utilization.
- Pick the instrument with the “adding” question. Counters count events, up-down counters hold additive levels, histograms hold the spread of values, and gauges hold the rest.
- Two styles exist. A synchronous gauge is pushed by your code when the value changes. An observable gauge is read by the SDK through a callback at each collection cycle.
- Only the last value survives. The default aggregation is last value, so anything that changes and recovers between collections is invisible. Use a maximum gauge, a shorter interval, or a histogram to catch spikes.
- Keep callbacks fast, read-only, and honest. Cache slow reads, report every label set each cycle, and never block collection.
- Mind labels and instances. Use small sets of attribute values, give each instance an identity, and combine series at query time with average, maximum, or minimum, never a meaningless sum.
- Protect and alert wisely. Encrypt and authenticate the pipeline, avoid sensitive labels, alert with time windows, and add a rule for missing data.