What Is an Observable Gauge in OpenTelemetry?
A plain-English guide to the OpenTelemetry instrument that reads the "current value" of things like temperature, utilization and ratios, how it works inside, when to use it, and the mistakes that quietly break dashboards.
Picture the dashboard of a car. The speedometer needle moves up and down as you drive. The fuel gauge slowly sinks. The engine temperature creeps up on a hot day. None of these dials care about the history of your trip. Each one answers a single simple question: “What is the value right now?”
Software systems have the same kind of dials. A server has a current CPU utilization. A cache has a current hit ratio. A battery in a sensor has a current charge level. A warehouse freezer has a current temperature. These numbers go up, they go down, and the question you ask about them is always “what is it right now?”
OpenTelemetry, the open standard for collecting telemetry from software, has a special tool built for exactly this job. It is called the Observable Gauge. In this guide you will learn what it is, why it is called “observable,” how it works step by step, how it is different from its sibling instruments, and which beginner mistakes to avoid. No prior knowledge is assumed. Every new word is explained the first time it appears.
Read the chapters in order the first time. Each chapter builds on the one before it. Later, you can jump straight to the chapter on common mistakes or the FAQ when you need a quick answer.
1The Big Picture: Observability, Telemetry and Metrics
Before we meet the Observable Gauge, we need to understand the world it lives in. This chapter explains the three words you will keep hearing: observability, telemetry and metrics.
When a program runs on your laptop, you can watch it directly. You can click buttons, read error messages and open the code. When a program runs in production, meaning on real servers serving real users, you usually cannot watch it directly. The servers might be in a data center thousands of kilometers away. There might be hundreds of copies of your program running at the same time. You cannot stand next to each one and look at it.
Observability is the ability to understand what is happening inside a system by looking at the information it sends out. If a system is observable, you can ask new questions such as “why did checkout get slow at 3 p.m.?” and find the answer from the data the system already produces, without having to change the program first.
The information a system sends out is called telemetry. The word comes from Greek roots meaning “measuring from far away.” Weather stations, space probes and medical heart monitors all send telemetry. Software does too.
The three main kinds of telemetry
Engineers usually talk about three kinds of telemetry, often called signals.
- Logs are timestamped text messages. Think of a ship captain’s diary: “10:02 a.m., storm approaching,” “10:40 a.m., changed course.”
- Traces follow one single request on its journey through many services. Think of the tracking page of a parcel that shows every warehouse it passed through.
- Metrics are numbers measured over time. Think of the dials on a car dashboard, written down once every few seconds.
This guide is about metrics. A metric is a measurement with a name, a number, a unit and some labels, recorded at a moment in time. When you collect the same metric again and again, you get a time series, which is simply a list of numbers in time order. Draw a time series on a chart and you get the familiar line graph on a monitoring dashboard.
Imagine a nurse walking through a hospital ward every ten minutes. At each bed, she writes down the patient’s temperature on a chart. The nurse is your monitoring system. The charts are your time series. The patient’s temperature is the metric. The nurse does not follow the patient everywhere. She simply visits, looks, and writes down what she sees. Keep this picture in mind, because it is exactly how the Observable Gauge behaves.
Why metrics are so popular
Metrics are small. A single number takes a few bytes, so even a company that tracks millions of numbers can store them cheaply. Metrics are fast to query, which is why dashboards load in a second. And metrics are perfect for alerting: “wake up the on-call engineer if CPU utilization stays above 90 percent for five minutes.” Logs and traces are richer, but they are heavier. Metrics give you the big picture quickly.
Now, not all metrics behave the same way. Some only ever go up, such as “total number of orders placed.” Some go up and down, such as “number of people currently in the shop.” Some describe a spread of values, such as “how long each request took.” OpenTelemetry gives each behavior its own tool, called an instrument. The Observable Gauge is one of these tools, and by the end of this guide you will know exactly which job it was made for.
2What Is OpenTelemetry?
OpenTelemetry is the toolbox that the Observable Gauge belongs to. Let us look at how the toolbox is organized.
OpenTelemetry, often shortened to OTel, is an open-source project under the Cloud Native Computing Foundation. It defines a common way to create, collect and send logs, traces and metrics. Before OpenTelemetry, every monitoring product had its own libraries and its own formats. If you wanted to switch from one product to another, you had to rewrite the measuring code inside your application. OpenTelemetry fixes this by giving everyone one shared standard. You write your measuring code once, and you can send the data to many different products, including Prometheus, Grafana, Datadog, New Relic, Honeycomb and the monitoring services of the big cloud providers.
Think of the universal power adapter you carry when you travel. Wall sockets differ from country to country, but your adapter lets your laptop charger work everywhere. OpenTelemetry is that adapter for monitoring data. Your application plugs into OpenTelemetry once, and OpenTelemetry handles the differences between monitoring products.
The main building blocks
For metrics, OpenTelemetry has a few important pieces. Learn their names now, because they appear again and again.
API
The set of functions your code calls to create instruments and record measurements. It is like the steering wheel of a car: simple and the same everywhere.
SDK
The actual implementation behind the API. It stores measurements, combines them, and decides when to send them out. It is like the engine under the hood.
MeterProvider and Meter
A MeterProvider is the factory that hands out Meters. A Meter is the object you ask to create instruments. Each Meter has a name that tells you which library or component it belongs to.
Instrument
The tool you use to take a specific kind of measurement. A Counter counts events. A Histogram records spreads. An Observable Gauge reads a current value.
Resource
A description of who is producing the data, such as the service name, the host name and the cloud region. Every measurement carries this name tag.
Reader and Exporter
The reader collects the measurements from the SDK on a schedule. The exporter sends them to another place, using a format such as OTLP.
OTLP stands for the OpenTelemetry Protocol. It is the standard language that OpenTelemetry components use to talk to each other. Think of it as the shared shipping container format that every port in the world agrees on.
There is one more important part: the OpenTelemetry Collector. It is a separate program that sits between your applications and your monitoring backend. It receives data, can clean it up or filter it, and forwards it onward. Many teams run a Collector on every machine or in every cluster, so the application only has to send its data to a nearby neighbor rather than to the faraway backend.
graph LR
A["Your Application Code"] --> B["Metrics API"]
B --> C["Metrics SDK"]
C --> D["Metric Reader"]
D --> E["OTLP Exporter"]
E --> F["OpenTelemetry Collector"]
F --> G["Prometheus"]
F --> H["Cloud Monitoring Backend"]
G --> I["Grafana Dashboards"]
Read the figure from left to right. Your application code calls the Metrics API. The SDK behind the API keeps track of the numbers. A metric reader collects them on a schedule. An exporter packs them into OTLP and ships them to the Collector. The Collector forwards them to one or more backends, and finally a dashboard tool such as Grafana draws the charts. Every instrument, including the Observable Gauge, travels this same road.
3Meet the Instrument Family
The Observable Gauge has six siblings. Seeing the whole family together makes it much easier to understand what makes the Observable Gauge special.
An instrument is a named tool that you create once and then use to report measurements. OpenTelemetry defines seven instruments. They differ along two questions. First, how does the measurement arrive: does your code push it in at the moment something happens (synchronous), or does the SDK ask for it later on a schedule (asynchronous)? Second, what kind of number is it: a total that only grows, a value that goes up and down, or a spread of many values?
| Instrument | How it is used | What it records | Everyday example |
|---|---|---|---|
| Counter | Synchronous | Positive increments that only add up | Orders placed |
| Observable Counter | Asynchronous | A running total that only grows, read on demand | Total bytes sent, as reported by the operating system |
| UpDownCounter | Synchronous | Additive changes that can be positive or negative | Items entering and leaving a basket |
| Observable UpDownCounter | Asynchronous | An additive current total, read on demand | Number of open connections |
| Histogram | Synchronous | A spread of individual values | How long each request took |
| Gauge | Synchronous | The current value, recorded when it changes | A volume slider being moved |
| Observable Gauge | Asynchronous | The current non-additive value, read on demand | Room temperature, CPU utilization |
Do not worry if the table feels like a lot. We will come back to each row. For now, notice the bottom row. The Observable Gauge is the asynchronous instrument for values that are non-additive. That word is the key to the whole story, and Chapter 6 is devoted to it.
Synchronous versus asynchronous
A synchronous instrument is used inside your normal program flow. When a customer places an order, your code runs a line that says “add one to the orders counter.” The measurement is recorded at the exact moment the event happens, and your code is the one that decides when.
An asynchronous instrument works the other way around. You do not push values in. Instead, you hand the SDK a small function, called a callback, which knows how to read the current value. The SDK calls that function whenever it needs fresh data, usually once every collection cycle. This is why asynchronous instruments are also called observable instruments: the SDK observes the value by asking for it.
A synchronous instrument is like a shopkeeper who rings a bell every time a customer walks in. An asynchronous instrument is like a security guard who walks through the building every ten minutes and writes down what the thermostat shows. The shopkeeper reports events as they happen. The guard reports a snapshot of the situation at each round.
A synchronous Gauge was added to the specification later than the others. Support for it depends on the language SDK and its version, so check your SDK’s documentation. The Observable Gauge, on the other hand, has been part of the metrics API from the start and is widely available.
4What Is an Observable Gauge?
Now we put the pieces together and give a clear definition, then walk through what each part of the definition means.
An Observable Gauge is an asynchronous instrument in the OpenTelemetry Metrics API that reports the current value of something that can go up and down, and whose values should not be added together across different sources. You give it a callback. At every collection cycle, the SDK calls your callback, your callback reads the current value from wherever it lives, and the SDK records that value as a measurement.
Let us unpack the definition word by word.
“Gauge”
A gauge is a dial that shows the current level of something. Pressure gauges, fuel gauges and rain gauges all work this way. The word tells you that the number means “how much is there right now,” not “how much happened in total.”
“Observable”
Observable means “can be looked at on demand.” Your code does not shout out the value every time it changes. Instead, the value just sits there, and the SDK looks at it when it is time to take a reading. The callback is the pair of eyes the SDK uses to look.
“Non-additive”
This is the subtle part. A value is additive if adding the values from several sources gives a meaningful answer. If server A handled 500 requests and server B handled 300 requests, the total of 800 is meaningful. A value is non-additive if adding the values makes no sense. If room A is 20 degrees Celsius and room B is 22 degrees Celsius, saying “the total temperature is 42 degrees” is nonsense. You might calculate an average, a minimum or a maximum, but never a sum. The Observable Gauge is designed for these non-additive values.
A thermometer on the wall is the perfect gauge. It does not remember what happened yesterday. It does not count anything. It just shows the temperature at this moment. If you want to know the temperature, you look at it. If you want a history, you write down the reading at regular times. That is exactly what OpenTelemetry does with an Observable Gauge: it looks at the thermometer on a schedule and writes down the number.
The ingredients of an Observable Gauge
Whenever you create an Observable Gauge, you provide a few things.
- A name, such as
room.temperature. This is how the metric is identified in your monitoring tool. - An optional unit, such as degrees Celsius. Units follow a standard code system called UCUM, where Celsius is written
Celand a plain ratio between zero and one is written1. - An optional description, a short sentence in plain words explaining what the number means.
- A callback, the small function that reads the current value and reports it. The callback can report one value, or many values with different attributes, which are labels such as
room=kitchenorroom=garage.
The same idea in every language
OpenTelemetry has official SDKs for many languages. The spelling changes to match each language’s habits, but the idea is identical.
Gauge builder with callback
In Java you ask the meter for a gauge builder and finish it by registering a callback. The same builder can produce integer or floating point gauges.
create_observable_gauge
In Python the meter has a method with this name. You pass the instrument name, a list of callbacks, and optionally a unit and description.
createObservableGauge
In JavaScript and TypeScript the meter has a method with this name. You then add a callback that receives an observation result object.
Int64 and Float64 variants
Go offers separate integer and floating point observable gauge types. You register the callback with an option when you create the instrument.
CreateObservableGauge
In .NET the Meter class has this method. It takes a function that returns the current measurement or a list of measurements.
Ruby, PHP, Rust, C++ and more
Each language follows the same specification. Support level and exact method names differ, so always check the documentation of your SDK version.
Because this guide is about understanding, not about typing code, we will focus on the idea. Once you understand the idea, translating it to your language takes a few minutes with the official documentation open next to you.
5Why “Observable”? The Callback Model Explained
The callback is the heart of the Observable Gauge. Understanding it clears up most of the confusion beginners have.
A callback is a function that you write now but that somebody else will run later. You are saying to the SDK: “Here is a recipe for reading the temperature. Whenever you want a fresh reading, follow this recipe.” You do not decide when it runs. The SDK does.
This is a very different style from the Counter. With a Counter, your code is in charge: it calls the instrument whenever something happens. With an Observable Gauge, the SDK is in charge: it calls your code whenever it is time to collect.
When does the callback run?
The callback runs during a collection. A collection happens when the metric reader asks the SDK for the current state of all metrics. There are two common styles of reader.
- Periodic push. A periodic exporting reader collects on a timer and pushes the result to a destination. The default export interval in many SDKs is 60 seconds, and teams often shorten it to 10 or 15 seconds for faster dashboards.
- Pull on request. A reader that serves a Prometheus-style endpoint collects every time the Prometheus server comes to scrape. If Prometheus scrapes every 15 seconds, your callback runs about every 15 seconds.
In both styles, the callback runs once per collection, not once per second and not once per request. That matters a great deal for how much work your callback can safely do.
sequenceDiagram
participant T as Timer or Scrape
participant R as Metric Reader
participant S as SDK
participant C as Your Callback
participant X as Thing Being Measured
T->>R: Time to collect
R->>S: Collect all metrics
S->>C: Please observe now
C->>X: Read current value
X-->>C: 22.5
C-->>S: Report 22.5 with attributes
S-->>R: Metric data ready
R-->>T: Send to exporter
Follow the arrows. A timer or a scrape request wakes up the reader. The reader asks the SDK to collect. The SDK calls your callback. The callback reads the thing being measured, such as a sensor, an operating system counter or an in-memory object, and reports the result back. The SDK packages the answer and the reader sends it onward. Between collections, nothing happens. The gauge is simply waiting for the next visit.
What this means in practice
Because the value is only read at collection time, an Observable Gauge gives you a sample of reality, not a full recording. If a temperature spikes for three seconds and falls back down between two readings, the gauge never sees the spike. This is not a bug. It is the nature of sampling, and it is an important thing to remember when you choose which instrument to use.
A callback should be quick, should not block while waiting on slow networks, should not crash, and should not report the same set of attributes twice in one run. The SDK may run it at awkward moments and, if several readers are configured, more than once per cycle. Treat it like a short, polite visit, not a long investigation.
Mini example: the freezer in a food warehouse
A food distribution company has 40 freezers. Each freezer has a sensor that can be read at any time. The team creates one Observable Gauge named freezer.temperature with the unit Cel. The callback loops over the sensors and reports one value per freezer, each with an attribute that names the freezer. Every 15 seconds, the SDK collects and the dashboard shows 40 lines. If a compressor fails and one freezer starts warming up, the line for that freezer rises, and an alert fires before the food spoils. Nobody had to write code that “pushes” a temperature on every tiny change. The gauge simply looked when it was asked to.
6Additive or Non-additive? Choosing the Right Instrument
The most common beginner question is “which instrument should I pick?” The answer almost always comes down to one test: can I meaningfully add these numbers together?
Let us make the test concrete. Imagine you run ten copies of a web service. Each copy reports a number. Now ask yourself: if I add up the ten numbers, do I get something useful?
- Requests handled. Adding gives the total traffic of the whole service. Useful. This is additive.
- Open connections. Adding gives the total connections across the whole service. Useful. This is additive.
- CPU utilization as a percentage. Ten copies each at 40 percent do not add up to 400 percent of anything useful. You would want the average or the maximum. This is non-additive.
- Cache hit ratio. Ten copies each at 0.9 do not add up to 9. The sum is meaningless. This is non-additive.
- Battery level. Ten batteries at 80 percent do not add up to 800 percent. This is non-additive.
When the numbers are additive, the specification points you toward a Counter or an UpDownCounter, because backends can safely add those values across sources. When the numbers are non-additive, it points you toward a Gauge, and when the value is read on demand, specifically toward the Observable Gauge.
Think of a classroom. The number of students present in each of five classrooms can be added to find the number of students in the school. That is additive. But the height of the tallest student in each classroom cannot be added to find “the height of the school.” You would take the maximum or the average instead. Additive numbers are like head counts. Non-additive numbers are like heights and temperatures.
graph TD
A["I want to measure something"] --> B{"Can the numbers from different sources be added into a meaningful total?"}
B -->|"Yes"| C{"Does it only ever go up?"}
B -->|"No"| D{"Do I already have the value when it changes?"}
C -->|"Yes, count of events"| E["Counter or Observable Counter"]
C -->|"No, goes up and down"| F["UpDownCounter or Observable UpDownCounter"]
D -->|"Yes, I can record it at that moment"| G["Gauge, synchronous"]
D -->|"No, I read it on demand"| H["Observable Gauge"]
A --> I{"Do I need the spread of many values, like response times?"}
I -->|"Yes"| J["Histogram"]
The figure above is a rough guide, not a law. Start at the top. If you care about the spread of many values, such as how long each request took, a Histogram is the right tool. Otherwise, ask whether the numbers can be added across sources. If they can, choose a Counter family instrument. If they cannot, choose a Gauge family instrument, and then ask whether you naturally have the value at the moment it changes or whether you would rather read it on a schedule.
Observable Gauge versus the synchronous Gauge
Both report a current, non-additive value. The difference is who decides when. With the synchronous Gauge, your code records the value at the moment it changes. A good example is a user dragging a volume slider: each time the slider moves, the code records the new volume level. With the Observable Gauge, the SDK reads the value on schedule. A good example is CPU utilization: the operating system always knows the value, and nobody in your code “makes it change.”
A simple rule of thumb: if the value changes because your code did something, consider the synchronous Gauge. If the value lives somewhere else and you simply want to look at it from time to time, use the Observable Gauge.
Observable Gauge versus Observable UpDownCounter
This pair confuses many people because both are observable and both go up and down. The difference is again additivity. The number of items waiting in a queue, summed across ten queue workers, tells you the total backlog. That is additive, so an Observable UpDownCounter fits. The utilization percentage of those same workers is non-additive, so an Observable Gauge fits.
Why does this matter if both just show a line on a chart? Because backends and the Collector sometimes combine data from many sources. A monitoring system that knows a metric is a sum can safely add values from many sources, while one that knows a metric is a gauge will keep each source separate or pick a last value. Choosing the right instrument tells every tool downstream how to treat your numbers.
Say the sentence “the total across all servers is …” out loud with your metric inside it. If the sentence makes sense, think Counter family. If it sounds silly, think Gauge family.
| What you measure | Additive? | Best instrument |
|---|---|---|
| Total orders ever placed | Yes | Counter |
| Total bytes sent, read from the operating system | Yes | Observable Counter |
| Number of open database connections | Yes | Observable UpDownCounter |
| Request duration for each request | Not applicable, it is a spread | Histogram |
| Volume level changed by a user | No | Gauge |
| CPU utilization of a server | No | Observable Gauge |
| Cache hit ratio | No | Observable Gauge |
| Room temperature | No | Observable Gauge |
7Anatomy of a Single Observation
Every time your callback reports a value, a small bundle of information is created. Knowing what is inside the bundle helps you design better metrics.
An observation is one reported value from your callback. When the SDK combines it with the instrument’s identity and the collection time, it becomes a data point in the final metric. Let us look at every piece.
Instrument name
The name says what the number is. Names are case-insensitive, may use letters, digits and a few symbols such as dots and underscores, and must start with a letter. A clear dotted style such as room.temperature keeps things tidy.
Unit
The unit says what the number counts: Celsius, bytes, seconds, or a plain ratio written as 1. A missing or wrong unit is a classic source of confusion when two teams compare charts.
Description
A short human sentence. It shows up in many tools as a tooltip or help text, which saves the next engineer a lot of guessing.
Value and its type
The value is either a whole number or a decimal number, and the type is chosen when the instrument is created. Use decimals for ratios and temperatures. Use whole numbers for things like a count of free slots.
Attributes
Key and value pairs that describe which thing the value belongs to, such as room=kitchen. One instrument can report many different attribute combinations in a single callback.
Timestamp
The moment the value was collected. The timestamp is added by the SDK, so your callback does not need to supply one.
Resource
The identity of the producer: service name, instance identifier, host, region and so on. This is attached to every data point automatically from the SDK configuration.
Instrumentation scope
The name and version of the library or component that created the instrument. It helps you tell apart metrics from your own code and metrics from a framework.
Attributes: the superpower and the danger
Attributes let one metric describe many things. Instead of creating forty instruments for forty freezers, you create one instrument and give each observation an attribute that names the freezer. Dashboards can then show all freezers, filter to one, or group by building.
But every unique combination of attribute values creates a separate time series. If you add an attribute such as user_id with a million different values, you have created a million time series from a single instrument. This is called high cardinality, and it is one of the fastest ways to make a monitoring bill explode and a dashboard crawl. SDKs protect you with a default limit on how many distinct series one instrument may produce, which the specification suggests should be 2,000 by default, and extra series are folded into an overflow bucket. Treat that as a safety net, not a design target.
Good attributes have a small, bounded set of values: region, freezer name, queue name, environment. Bad attributes grow without limit: user identifiers, request identifiers, full URLs with query strings, timestamps.
Think of a school notice board with one column per class. Ten classes mean ten columns, which is easy to read. If you made one column per student, the board would cover the whole building and nobody could read it. Attributes are the columns. Keep the number of columns small enough that a human could still read the board.
8Internal Working: From Callback to Data Point
Now we open the hood. This chapter follows one reading, step by step, from the moment the instrument is created to the moment a number is ready to leave the application.
Setup: the provider and the reader are configured
When the application starts, it creates a MeterProvider. It attaches a Resource that describes the service, and it attaches one or more metric readers, each with its own exporter. Think of this as hiring the nurse and giving her a route and a schedule.
Registration: the instrument and callback are created
The code asks a Meter to create an Observable Gauge with a name, unit, description and callback. The SDK remembers this instrument and its callback. Nothing is measured yet. The recipe is simply filed away.
Trigger: a collection begins
A timer fires, or a Prometheus server scrapes the endpoint. The metric reader tells the SDK to produce the latest metrics.
Observation: the callback runs
For every registered asynchronous instrument, the SDK calls its callback. The callback reads the current value from the real world and hands one or more observations, each with optional attributes, back to the SDK.
Aggregation: observations become data points
The SDK applies an aggregation to the observations. For a gauge, the default is called Last Value: for every distinct set of attributes, keep the latest value. Because an observable gauge is usually read once per collection, the last value is simply the value that was just read.
Export: the data leaves the application
The reader hands the finished metric data to the exporter. The exporter converts it into the target format, usually OTLP, and sends it to the Collector or directly to a backend.
About aggregation and temporality
Two words from the specification are worth knowing. Aggregation means how the SDK combines many measurements into one data point. Temporality means whether a data point describes the total since the program started (cumulative) or only the change since the last report (delta). Temporality matters a lot for counters and histograms, because a total and a change are very different things. For a gauge, however, temporality does not apply. A temperature is a temperature; it is not “cumulative” or “delta.” This is one reason gauges are the simplest instrument to reason about.
Views: changing the default behavior
The SDK has a feature called views. A view is a rule that lets operators change how an instrument is processed without touching the instrumented code. With a view you can rename a metric, drop attributes you do not need, choose a different aggregation, or turn off a metric completely. This is very handy when a library you do not control produces an Observable Gauge with too many attributes. You can trim it from the outside.
What if you have more than one reader?
It is allowed to configure several readers, for example one that pushes to a cloud backend and another that serves a local Prometheus endpoint. In that case each reader performs its own collections on its own schedule, and the callback can be invoked once for each. This is why callbacks must be safe to run repeatedly and must not rely on being called exactly once per interval.
If a callback throws an error, a well-behaved SDK catches it, logs it, and carries on with the other instruments. For that cycle you simply get no data from that instrument. This is better than crashing, but it also means failures can be quiet. Chapter 20 shows how to notice them.
9Data Flow and Lifecycle of a Gauge Series
A reading does not stop at the application. It travels through several hands before it becomes a point on a chart. Let us follow the whole journey and then see how a series is born and how it fades away.
graph LR
A["Sensor or Operating System"] --> B["Callback"]
B --> C["SDK Last Value Aggregation"]
C --> D["Periodic Reader"]
D --> E["OTLP Exporter"]
E --> F["Collector Receiver"]
F --> G["Processors: batch, filter, add attributes"]
G --> H["Collector Exporters"]
H --> I["Time Series Database"]
I --> J["Dashboards and Alerts"]
Start at the left. The real world holds the value: a sensor, the operating system, a counter in memory. The callback reads it. The SDK keeps the last value per attribute set. The periodic reader picks it up on schedule, and the OTLP exporter ships it to the Collector.
Inside the Collector, a receiver accepts the incoming data. Then processors work on it in order. A common processor is the batch processor, which groups many small points into bigger packages so the network is used efficiently. Another is an attribute processor, which can add or remove labels. Finally, exporters send the data to one or more destinations, such as a time series database. Dashboards and alert rules read from that database.
Think of a postal service. You write a letter (the reading). A local post box collects it (the SDK). A postman takes it to the sorting center on a schedule (the reader and exporter). The sorting center (the Collector) groups letters, checks addresses, and sends them to the right city (the backend). Finally the letter is delivered to the reader of the dashboard. The Collector is the sorting center that protects your application from knowing about every destination.
Life of a time series
Every unique combination of instrument name and attribute values forms one time series. For asynchronous instruments, the life of a series is controlled by what the callback reports.
- Birth. The first time the callback reports a new attribute combination, such as a newly installed freezer, a new series starts.
- Life. As long as the callback keeps reporting that combination at each collection, the series keeps growing, one point per cycle.
- Silence. If the callback stops reporting that combination, for example because the freezer was removed, the SDK does not invent a value. The series simply gets no new points.
- Staleness. Backends notice the silence. Prometheus, for example, treats a series as stale a few minutes after its last point, so it disappears from charts and instant queries.
This behavior is useful. When something is removed from the real world, its gauge quietly fades away instead of showing a false flat line. But it also means a series that disappears unexpectedly deserves attention, because “no data” might mean “the thing broke” rather than “the thing was removed.”
Where the resource fits in
Every point carries the resource of its producer. Suppose five copies of a service each report cpu.utilization. The resource, which includes the service name and a unique instance identifier, keeps the five series apart. Without it, five different values would fight over the same series and the chart would jump around randomly. Setting a proper instance identifier is a small step that prevents a large headache.
10Real-World Use Cases
Theory is easier to hold when you see where it applies. Here are common places where an Observable Gauge is the natural choice. The scenarios are illustrative examples to build intuition, not descriptions of any particular company’s internal systems.
1. CPU and memory utilization of a host
The operating system always knows how busy the processor is. A callback asks for the current utilization, as a ratio between zero and one, and reports it with the unit 1. Because utilization of different machines cannot be added, an Observable Gauge is the right fit. The OpenTelemetry Collector even ships a host metrics receiver that gathers many such values from a machine without writing any code.
2. Temperature sensors in a cold chain
Pharmacies, food distributors and vaccine suppliers must keep goods cold. Each sensor can be read on demand. One gauge with an attribute per sensor gives a clear dashboard and an alert that fires when any sensor stays above a limit for too long.
3. Cache hit ratio
A cache keeps two simple internal totals: hits and lookups. A callback divides one by the other and reports the ratio. A ratio is non-additive, so a gauge is correct. The team watches it to decide whether the cache is the right size. If the ratio drops after a release, something changed in how data is requested.
4. Connection pool saturation
A database connection pool has a maximum size and a number currently in use. A callback reports the percentage in use. When the percentage hovers near 100, requests start to wait for a free connection, and the team knows to raise the limit or fix a slow query before users feel it.
5. Battery level of field devices
Delivery scooters, trackers and Internet of Things devices carry batteries. A gauge for battery level with an attribute for the device group lets operations staff plan charging rounds. Summing batteries makes no sense, so the gauge is the honest choice.
6. Disk free space ratio
A callback checks the free space on each mounted disk and reports it as a ratio. An alert for “less than 10 percent free” gives engineers hours or days of warning before a disk fills up and a database refuses to write.
7. Business state that is read from somewhere else
Sometimes the value is not technical at all. A ride-hailing style marketplace might track the ratio of waiting riders to available drivers in a zone. A retail business might track the age in minutes of the oldest unprocessed order. These are current-state numbers that can be read on schedule, and gauges capture them well.
Many OpenTelemetry instrumentation libraries and agents for runtimes and frameworks use asynchronous instruments internally to publish runtime health numbers. So even if you never write a callback yourself, you are probably looking at gauge data on your dashboards today.
11Design Patterns for Observable Gauges
A design pattern is a proven way of solving a problem that keeps coming back. These are the patterns engineers use most often with Observable Gauges.
Read the source of truth
Let the callback read the value directly from where it already lives, such as the operating system, a connection pool object or a sensor library. Do not keep a second copy that can drift out of date.
Cached reader
When the real value is slow or expensive to fetch, let a background task refresh it every few seconds and store it in memory. The callback then just reads the stored number, which takes microseconds.
Ratio gauge
Instead of exporting two raw totals and dividing later, compute the ratio inside the callback when the ratio is the number people actually care about, such as hit ratio or saturation percentage.
One instrument, many attributes
Create one gauge for “temperature” and report each sensor with an attribute, rather than creating a separate gauge for every sensor. Dashboards stay simple and new sensors need no new code.
Batch callback
When one single reading produces several values, such as one system call that returns processor, memory and disk numbers together, many SDKs let one callback feed several instruments at once. This avoids reading the same source several times.
Adapter over an existing registry
If your application already tracks its own internal health numbers, write a thin callback that translates them into OpenTelemetry. You get standard telemetry without rewriting the old code.
The cached reader pattern in more detail
Imagine the callback needs to ask a remote server for a number, and the server sometimes takes two seconds to answer. If the callback waits for that answer, the whole collection waits. If several callbacks do this, the collection can take longer than the interval between collections, and data will be late or lost.
The cached reader pattern separates the slow part from the fast part. A background worker fetches the number every ten seconds and stores it. The callback only looks at the stored number. The result is a collection that is always fast, at the price of data that can be up to one refresh interval old. For most monitoring needs that is a very good bargain.
A restaurant waiter does not walk to the farm every time a customer asks whether the tomatoes are fresh. The kitchen checks the stock a few times a day and writes it on a board. The waiter simply reads the board. The board is the cache, and the kitchen check is the background worker.
When you use a cached reader, it is wise to also expose how old the cached value is as its own gauge. If the age grows, you know the background worker is stuck, and you will not trust a stale number by accident.
12Advantages, Disadvantages and Trade-offs
No tool is perfect for every job. An honest look at the strengths and weaknesses of the Observable Gauge helps you decide when to reach for it and when to put it down.
Advantages
- Perfect match for “current value” numbers such as temperature, utilization and ratios.
- No work on the hot path of your application, because values are read only at collection time.
- Collection cost is predictable: one callback run per collection, not one per event.
- Reads the real source of truth, so numbers cannot drift from reality.
- Tells downstream tools that the values are non-additive, so they are never summed by mistake.
- Simple aggregation: last value, with no confusing temporality to think about.
- Works the same way in every OpenTelemetry language.
Disadvantages
- It is a sample: spikes that happen between two collections are invisible.
- A slow or broken callback can delay or silently remove data.
- Resolution is limited by the collection interval, often 10 to 60 seconds.
- Not suitable for events, totals or distributions.
- Callbacks must be safe to run at any moment and possibly more than once per cycle.
- Careless attributes can create very large numbers of series.
- Data may be a little old if you use a cached reader.
The central trade-off: freshness versus cost
Shorter collection intervals give finer detail and quicker alerts, but they cost more. Each collection runs every callback, creates data points, sends them over the network and stores them. Halving the interval roughly doubles the data volume. Many teams start with 60 seconds, move important services to 15 seconds, and keep only a few critical gauges at 5 seconds.
Comparing the two gauge styles
| Question | Observable Gauge | Synchronous Gauge |
|---|---|---|
| Who decides when the value is recorded? | The SDK, on every collection | Your code, when the value changes |
| Best when | The value lives somewhere you can read on demand | Your code knows the new value at the moment of change |
| Work on the application’s hot path | None | A small amount at every change |
| If nothing changes | Still reported at each collection | Nothing is recorded until the next change |
| Typical example | CPU utilization, sensor reading | User changes a setting slider |
| Availability | Available in all major SDKs | Newer, check your SDK version |
When not to use an Observable Gauge
- When you need to count events, use a Counter.
- When you need to know how long things took or how big they were, and you want percentiles, use a Histogram.
- When the values can be meaningfully added across sources, use a Counter or an UpDownCounter, or their observable versions.
- When you must never miss a short spike, such as a brief overload, record each event with a Histogram or Counter instead of sampling a gauge.
13Common Mistakes and Anti-patterns
These are the mistakes that appear again and again in real systems. Each one looks harmless at first, and each one can make dashboards lie or bills grow.
The mistake
Using an Observable Gauge for a running total, such as “total orders so far,” or summing gauge values from different servers to get a grand total.
Why it hurts
A gauge is meant to show the current level, and backends treat it as non-additive. A total belongs in a Counter, where tools know how to compute rates and handle restarts. Summing temperatures or utilization percentages produces numbers that mean nothing.
Better approach
Use a Counter or an Observable Counter for totals. Use averages, minimums or maximums when you need to combine gauge values from many sources.
The mistake
Doing slow work inside the callback: calling a remote service, running a large database query, or reading a big file on every collection.
Why it hurts
The callback runs during collection. If it is slow, collection becomes slow, exports become late, and other instruments suffer. A failing network call can make the whole metrics pipeline stall or time out.
Better approach
Use the cached reader pattern. Let a background task do the slow work and let the callback read a number from memory.
The mistake
Adding attributes with unbounded values, such as a user identifier, session identifier or full web address, to every observation.
Why it hurts
Every distinct value creates a new time series. Storage and query costs grow quickly, dashboards become slow, and the SDK may start folding data into an overflow series, which makes the numbers hard to trust.
Better approach
Use attributes with a small, known set of values. If you truly need per-user detail, use traces or logs, which are built for high-detail data.
The mistake
Reporting the same set of attributes more than once in one callback run, or letting two different callbacks both report the same attribute combination for one instrument.
Why it hurts
The specification treats duplicate observations as undefined behavior. Depending on the SDK, you may get one value, the other value, or an error. Charts will show a confusing jitter.
Better approach
Make sure every attribute combination is reported exactly once per collection. If two parts of your code feed the same instrument, give them different attributes.
The mistake
Expecting an Observable Gauge to catch short spikes, or alerting on a gauge as if it were a continuous recording.
Why it hurts
A gauge only sees the moments when it is read. A ten-second overload can fall completely between two 60-second collections and never appear in your data, so the dashboard looks calm while users suffer.
Better approach
Where peaks matter, record events with a Histogram, or report an extra gauge for the maximum value seen since the last collection, computed by your own code.
The mistake
Wrong or missing units, and unclear names, for example one team reporting temperature in Fahrenheit and another in Celsius under the same name.
Why it hurts
Dashboards compare numbers that cannot be compared. Alerts fire at the wrong thresholds. People lose trust in the charts.
Better approach
Always set the unit, use standard unit codes, and write a one-line description. Agree on naming conventions across teams before the first metric is shipped.
14Best Practices
These habits keep Observable Gauges accurate, cheap and easy to understand. Think of them as a checklist you run through whenever you add a new gauge.
Name for meaning
Use short, lowercase, dotted names that describe what is measured, such as freezer.temperature. Do not put the unit or the word “gauge” into the name, because the unit has its own field.
Always set the unit
Use standard codes. A fraction between zero and one is 1. Bytes are By. Seconds are s. Celsius is Cel. Prefer ratios between zero and one over percentages unless your conventions say otherwise.
Keep callbacks fast
Aim for a few milliseconds. Never block on a network. Use the cached reader pattern for anything slow.
Make callbacks safe
Catch your own errors, do not change shared state without protection, and design for being called more than once or from a different thread than you expect.
Bound your attributes
Before adding an attribute, ask “how many different values can this have?” If the answer is “thousands” or “unlimited,” leave it out.
Set a good resource
Give every service a clear service name and every running copy a unique instance identifier, so series from different copies never collide.
Choose the interval on purpose
Match the interval to how fast the value changes and how quickly you need to react. Slow-moving values such as disk space do not need a five-second interval.
Write the description
One sentence about what the number means and what a high or low value indicates. Future you, and your teammates at 3 a.m., will be grateful.
A short pre-launch checklist
- Is this value truly non-additive and read on demand? If not, reconsider the instrument.
- Does the callback finish quickly and handle its own errors?
- Does each attribute combination appear only once per collection?
- Are the unit, name and description clear?
- How many series will this create at full production scale?
- Is there a dashboard or alert that will actually use this number? A metric nobody looks at is only a cost.
15Security, Privacy and Cost
Metrics look harmless because they are just numbers. But numbers and their labels can reveal more than you expect, and they can cost real money.
Security
Telemetry flows through several systems, so each hop deserves protection.
- Encrypt the transport. Use secure connections between applications, the Collector and the backend, so nobody can read or change data on the way.
- Authenticate senders. Backends and Collectors should accept data only from trusted sources, using tokens or certificates. Otherwise an attacker could flood your system with fake readings or hide a real problem.
- Least privilege inside callbacks. A callback that reads a database or a file should use credentials that can only read what it needs. A monitoring hook should never have the power to change or delete data.
- Protect the endpoint. If your application exposes a Prometheus-style scrape endpoint, do not leave it open to the whole internet. Restrict it to your monitoring network.
- Keep the Collector updated. It is a program that handles all your telemetry, so it should receive security updates like any other critical component.
Privacy
Attributes are text labels, and it is easy to put something sensitive into them without noticing: an email address, an account number, a patient name, a full web address that carries a secret token. Once it is in a metric label, it is copied to every system that stores or displays that metric, and it may live there for months.
The safest rule is simple: never put personal or secret data into metric attributes. Use stable, harmless identifiers such as a region name or a sensor group. The Collector can also scrub or drop attributes with processors, which gives you a second line of defense.
Unbounded attributes are a cost problem and a privacy problem at the same time. A user identifier as a label creates a huge number of series and also spreads personal data into your monitoring tools.
Cost
Monitoring bills usually grow with two things: the number of active time series and the number of data points stored per second. Observable Gauges affect both.
To estimate the data volume of a gauge, multiply the number of series by the number of collections per day. For example, 40 freezers collected every 15 seconds produce 40 times 5,760, which is 230,400 points per day for that one gauge. That is tiny. But 50,000 devices collected every 10 seconds produce more than 400 million points per day, and that deserves planning.
To keep costs under control, use sensible intervals, keep attributes bounded, drop gauges nobody uses, and use views or Collector processors to filter data you do not need. Some teams also keep fine-grained data for a few days and keep only averages for longer periods.
16Step-by-Step: Designing Your First Observable Gauge
Knowing the parts is one thing. Putting them together in a sensible order is another. This chapter walks through the thinking, without any code, so that you can design a gauge confidently for your own system.
Let us use a friendly example: an online bakery that sells cakes. The kitchen has several ovens, and the owner wants to be warned if any oven drifts away from its target temperature. We will design the gauge from a blank page.
Write down the question
Start with a plain sentence: “Is any oven too hot or too cold right now?” A metric should always exist to answer a question. If you cannot write the question, you probably do not need the metric.
Run the additivity test
Say it aloud: “the total temperature across all ovens is …” That sounds silly, so the number is non-additive. We are in gauge territory. Next, ask whether we can read the temperature whenever we like. Yes, each oven has a probe. So the right tool is an Observable Gauge.
Choose the name, unit and description
The name could be oven.temperature. The unit is Celsius, written Cel. The description reads: “Current temperature measured by the oven probe.” Notice that the name does not contain the word “celsius,” because the unit has its own field.
Decide the attributes
We need to tell ovens apart, so we add an attribute for the oven name, such as “oven one” and “oven two.” The bakery has six ovens, so that is six series. We also might add the kitchen location if there are several branches. We deliberately do not add the name of the cake being baked, because that changes all the time and has too many possible values.
Decide where the callback reads from
The probes are slow to answer when asked directly, so the team uses the cached reader pattern. A small background task polls the probes every five seconds and keeps the latest numbers in memory. The callback only reads those stored numbers.
Pick the collection interval
Ovens change temperature over minutes, not milliseconds. A collection every 15 seconds is plenty. A five-second interval would triple the data without adding much value.
Plan the dashboard and alerts
A line chart with one line per oven, with a shaded band for the safe range. An alert fires if any oven stays outside the safe range for five minutes. A second alert fires if an oven stops reporting for two minutes.
Review for cost, privacy and safety
Six series every 15 seconds is a very small cost. No personal data is in the labels. The callback is fast and cannot throw because it only reads memory. The design is ready to build.
Designing a gauge is like planning a school timetable before the term starts. You decide which questions matter, who needs to be where, and how often they meet. If you plan well, the term runs smoothly. If you skip the planning and add classes randomly, you end up with clashes and empty rooms. A few minutes of design saves months of cleaning up bad metrics.
Write the design down in a few lines in your team’s wiki: the question, the instrument, the name, the unit, the attributes and the alert. Future engineers will understand why the gauge exists, and they will be less tempted to add risky labels.
17Observable Gauges Across Prometheus, the Collector and Cloud Backends
OpenTelemetry is only the first half of the story. The data must be understood by a backend. Here is how gauges are treated as they move through the most common destinations.
The data model underneath
OpenTelemetry defines a data model that describes what every metric looks like on the wire. Several metric shapes exist: sums, histograms and gauges, among others. A gauge data point in this model holds a few simple things: the attributes, the time of the reading and the value, which is either a whole number or a decimal. Notice what is missing. There is no “monotonic” flag and no temporality, because those ideas simply do not apply to a gauge. This simplicity is why gauges travel so smoothly through the pipeline.
Prometheus
Prometheus is one of the most popular open-source monitoring systems. It has its own metric types, and the one that matches an OpenTelemetry gauge is also called a gauge. When OpenTelemetry data reaches Prometheus, either through a scrape endpoint on your application or through the Collector, an Observable Gauge becomes a Prometheus gauge, and your attributes become labels.
There are a few things to watch for. Prometheus has strict rules for names and labels, so characters such as dots are converted to underscores. Some exporters add the unit to the name, so a metric named oven.temperature with the unit Celsius may appear with a suffix describing the unit. Resource information such as the service name is often moved into special labels or a dedicated info metric. Because the details depend on the exporter version and settings, the safest habit is to look at the real name in the Prometheus user interface before you write a dashboard query.
Prometheus also has its own idea of staleness. If a series stops appearing in a scrape, it is marked stale and vanishes from instant queries after a short time. This lines up nicely with how asynchronous instruments behave when a callback stops reporting an attribute combination.
The OpenTelemetry Collector
The Collector treats gauges as one more metric shape. It can receive them over OTLP, transform them, and export them to many backends. A few processors are especially relevant to gauges.
- A batch processor groups points for efficient sending.
- An attributes or resource processor adds, changes or removes labels, which is a handy way to enforce your cardinality and privacy rules centrally.
- A filter processor drops metrics you do not want to pay for.
- A memory limiter protects the Collector from running out of memory under heavy load.
The Collector also has receivers that produce gauges by themselves. The host metrics receiver is a good example: it reads machine-level numbers such as processor utilization, memory and disk figures and emits them without any code in your application. Using it for machine-level data and your own Observable Gauges for application-level data is a clean division of labor.
Cloud and commercial backends
Most commercial monitoring products and cloud monitoring services accept OpenTelemetry data, either directly over OTLP or through a vendor-supplied distribution of the Collector. They map an Observable Gauge to their own concept of a gauge or “last value” metric. The mapping is almost always straightforward, but two points deserve a check: how they treat units, and how they limit the number of distinct series per metric. Read the backend’s documentation for its limits before you launch a gauge with many attributes.
| Place | What it does with a gauge | Watch out for |
|---|---|---|
| OTLP on the wire | Carries attributes, timestamp and value as a gauge shape | Nothing special, it is the common language |
| Collector | Receives, processes and forwards it unchanged unless you configure otherwise | Filters or processors that drop or rename it by accident |
| Prometheus | Stores it as a gauge series with labels | Name changes, unit suffixes and label rules |
| Cloud and commercial tools | Stores it as a last-value or gauge metric | Series limits, retention and pricing by active series |
Because the gauge data shape is so simple, switching backends later is usually easy. That is exactly the freedom OpenTelemetry was created to give you: the code that reads the oven temperature stays the same even if the place the numbers are sent changes.
18Gauges in Large Distributed Systems
A gauge in a small program is simple. A gauge across thousands of copies of a service running in many regions raises new questions. This chapter covers the ones that matter most.
Many copies, one metric name
In a big system, the same program runs on hundreds or thousands of instances. Each instance has its own Observable Gauge with the same name, and each reports its own value. Thanks to the resource, every instance produces its own series, tagged with the service name and a unique instance identifier. The backend therefore holds one series per instance.
Now someone asks, “how busy is the service overall?” The answer is not a sum. It is a statistic: the average utilization across instances, the maximum to find the busiest instance, and perhaps a high percentile such as the ninety-fifth to see how unevenly the load is spread. This is the main reason the specification makes you choose a gauge for non-additive values. It reminds everyone down the line to combine them with statistics rather than with addition.
Think of a chain of bakeries across a country. Each shop reports the temperature of its main oven. The head office does not add them up. It looks at the hottest and coolest shops, the average, and any shop that is far from the others. The same applies to servers: you compare, you do not sum.
Choosing a collection interval at scale
With a thousand instances reporting every ten seconds, a single gauge with a handful of attributes produces millions of points per day. If you have hundreds of gauges, the numbers add up fast. Large organizations often choose a default interval of 30 or 60 seconds, then lower it only for the gauges that drive fast alerts. They also use the Collector to keep a short-term, high-resolution copy of important data while storing a smaller, averaged copy for the long term.
Keeping the pipeline healthy under load
When many applications send data to a Collector at the same time, the Collector needs enough memory and processing power. Common protections include running several Collector instances behind a load balancer, giving each a memory limiter, using queues with retry so that short outages do not lose data, and sizing batches sensibly. If the backend slows down, queues fill up. A good setup drops the oldest data in a controlled way rather than crashing the whole Collector.
Because gauges represent the present, old gauge data is usually worth less than old counter data. A temperature reading from an hour ago, delivered late, is rarely important when you already have newer readings. That makes gauges a sensible candidate for “drop when overloaded” rules, while totals and counts deserve stronger delivery guarantees.
Clocks and time
Each reading carries a timestamp. If a machine’s clock is wrong by several minutes, its gauge points will appear at the wrong place on the chart, or be rejected by a backend that does not accept data from the future or far past. Keeping all machines synchronized with a time service is a quiet but essential part of reliable monitoring.
Restarts, deployments and autoscaling
- Restarts cause a short gap in a gauge and then it resumes. Because gauges do not accumulate, there is no reset problem.
- Rolling deployments create new instances with new instance identifiers, so old series end and new ones begin. Dashboards that group by instance will show this churn, so group by service for steady charts.
- Autoscaling adds and removes instances during the day. Make sure alerts are written against statistics across the service, not against the existence of one particular instance.
- Short-lived jobs that run for less than one collection interval may never be observed at all. For batch jobs and scripts, report their results with a different approach, such as recording a final value just before they exit.
Illustration: a global streaming-style service
Imagine a video streaming service running in many regions, with tens of thousands of instances of a recommendation service. Each instance reports one Observable Gauge for the fill ratio of its in-memory cache. The monitoring team does not chart every instance. Instead, they chart the average ratio per region and the lowest ratio per region. A sudden drop in the lowest value points to a single unhealthy instance, which the autoscaler can replace. This is a made-up illustration to show the thinking, not a description of any real company’s setup.
19Testing and Validating a Gauge Before Production
A metric that is wrong is worse than no metric, because people trust it and make decisions with it. A little testing before launch prevents most embarrassing mistakes.
Test the callback by itself
The callback is ordinary program logic, so it can be tested like any other function. Replace the real source, such as a probe or an operating system call, with a fake that returns known values, and check that the callback reports the expected numbers with the expected attributes. Also test the unhappy paths: what does the callback do if the source returns nothing, returns an impossible value, or throws an error? A good callback reports nothing for a broken source rather than a misleading zero.
Reporting 0 when a source is unavailable looks like “all good” on many charts. A temperature of zero degrees or a utilization of zero percent is a valid reading and will not trigger “no data” alerts. When a value cannot be read, it is usually better to report nothing at all.
Test the whole path with an in-memory reader
Most SDKs offer a metric reader that keeps collected data in memory instead of sending it away. In a test, you can configure the provider with such a reader, create your gauge, trigger a collection, and then inspect what was produced: the metric name, unit, value and attributes. This is a fast way to catch typos in names, wrong units and missing attributes without needing a real backend.
Test with realistic scale
Before a launch, estimate how many series the gauge will create in production: multiply the number of values of each attribute together, then multiply by the number of instances. Run a staging environment with similar numbers and watch the memory use of the application, the time the callback takes, and the load on the Collector and backend. Surprises are much cheaper to discover in staging.
Test the alert, not just the number
The final test is whether the gauge actually helps someone act. Cause a controlled problem in a test environment, such as turning down an oven target in a simulator or filling a test disk, and confirm that the chart moves and the alert fires and reaches the right person. Many teams discover at this stage that an alert was sent to a channel nobody reads, or that its threshold was set in the wrong unit.
A validation checklist
Correct name and unit
The metric appears in the backend with the name and unit you intended, and different teams read it the same way.
Correct values
The numbers on the chart match an independent source, such as a command-line tool, a manual probe reading or the operating system’s own display.
Correct attributes
Every attribute has a small, known set of values, and no sensitive information appears in any label.
Callback speed
The callback finishes in a few milliseconds, even under load, and does not block on slow resources.
Failure behavior
When the source breaks, the gauge goes quiet instead of lying, and a missing-data alert fires.
Cost
The projected number of series and points per day fits the monitoring budget with room to spare.
20Monitoring, Alerting and Troubleshooting
Once your gauges are flowing, two new jobs begin: using the data well, and making sure the data itself stays healthy.
Reading gauge data on dashboards
Because a gauge shows a current level, it is usually drawn as a simple line chart. A few habits make these charts more useful.
- Compare across sources with statistics, not sums. To see how a group of servers is doing, show the average, the maximum and sometimes the minimum, instead of the total.
- Use the maximum for danger. If one freezer out of forty is too warm, the average still looks fine. The maximum tells you the truth.
- Smooth over time with care. Query tools let you take the average or maximum of a gauge over a window of time, for example the highest value in the last five minutes. This helps you catch spikes that a single reading would miss, as long as readings are frequent enough.
- Show the threshold. Draw a horizontal line for the limit you care about, so the chart answers “are we safe?” at a glance.
Alerting on gauges
Gauges are natural candidates for threshold alerts. A good alert has three parts: a clear condition, a duration, and a severity. “CPU utilization above 90 percent for ten minutes” is much better than “CPU utilization above 90 percent right now,” because a short burst is normal but a long plateau is a problem.
Another valuable alert is for missing data. If a gauge that normally reports every 15 seconds suddenly goes silent, that is an incident in itself. It can mean the application crashed, the callback is failing, or the pipeline is broken. Without a “no data” alert, a silent gauge looks just like a healthy system with nothing to report.
An alert that depends on a gauge is only as trustworthy as the callback behind it. Always pair value alerts with a missing-data alert for the same gauge.
Monitoring the monitoring pipeline
The OpenTelemetry Collector exposes its own internal metrics, such as how many data points it received, how many it sent, how many it refused and how full its queues are. Watching these tells you whether your telemetry is arriving safely. SDKs can also log errors from callbacks and exporters. Make sure those logs go somewhere a human can find them.
A troubleshooting walk-through
Suppose a gauge you expect to see is missing or looks wrong. Work from the closest point to the farthest.
Is the callback registered and running?
Confirm that the instrument is created at application start and not garbage collected or created inside a short-lived function. In some languages, the instrument or callback must be kept alive, or it can be cleaned up and stop reporting.
Is the callback returning real values?
Check for errors in the SDK logs. Look for cases where the callback throws, returns nothing, or reports a value of the wrong type for the instrument.
Is the reader collecting?
Verify that a reader is attached to the provider and that the export interval is what you expect. A common surprise is a very long default interval making the data look sparse.
Is a view hiding or changing it?
Check whether any view renames, filters or drops the metric. Views are powerful and easy to forget about.
Is the data reaching the Collector and the backend?
Look at the Collector’s own metrics for received and exported points, check for refused data or full queues, and confirm that network rules and credentials allow the traffic through.
Is the query asking for the right thing?
Some backends change metric names, for example by appending the unit. Search the backend for the metric by a partial name and look at its attributes before assuming the data is missing.
A very effective habit is a single “heartbeat” gauge in each service that always reports the number 1. If the heartbeat disappears from the dashboard, you know right away that the whole telemetry path for that service is broken, not just one metric.
21Frequently Asked Questions
Short, direct answers to the questions beginners ask most often.
1, because it is easy to convert for display. The most important thing is to be consistent across your teams and to document it in the description.22Summary and Key Takeaways
You started with a car dashboard and ended with a full picture of how an Observable Gauge works from callback to chart. Here is everything that matters, in one place.
The Observable Gauge is the OpenTelemetry instrument for “what is the value right now?” You register a small callback once. The SDK calls it on every collection, the callback reads the current value from the real world, and the value travels through the reader, the exporter and usually the Collector to your dashboards and alerts. Because it only looks when asked, it adds no cost to your application’s busy paths, but it also means it sees a sample of reality rather than a full recording. Choosing it correctly, keeping callbacks fast, keeping attributes bounded and always setting clear units are the habits that make it a dependable tool.
Key Takeaways
- What it is: an asynchronous instrument that reports the current, non-additive value of something through a callback that the SDK runs on every collection.
- When to choose it: use it for values you can read on demand and should never add up across sources, such as temperature, utilization, ratios and battery level.
- When not to: use Counters for totals, UpDownCounters for additive levels, Histograms for spreads and spikes, and the synchronous Gauge when your code knows the value at the moment it changes.
- How it works: timer or scrape, then reader, then SDK, then your callback, then Last Value aggregation, then exporter, then Collector, then backend.
- Keep callbacks light: fast, safe, error-handled and free of duplicate attribute combinations; use a cached reader for slow sources.
- Keep attributes small: bounded labels protect your budget, your dashboards and your users’ privacy.
- Watch the watcher: add missing-data alerts, monitor the Collector, and remember that a gauge is a sample, so peaks need other tools.