Skip to main content
A Gauge is a synchronous instrument that records independent, non-additive values. Gauges are ideal for measurements where only the current value matters, such as CPU usage, memory consumption, or temperature.

When to Use Gauge

Use a Gauge when:
  • Only the current/latest value is meaningful
  • Values are independent measurements (not cumulative)
  • You’re measuring instantaneous state
  • Historical values aren’t aggregated
Common examples:
  • CPU usage percentage
  • Memory consumption
  • Temperature readings
  • Cache size
  • Queue depth at a point in time
  • Thread pool size
Gauges record point-in-time values. The last value recorded is what gets exported. Unlike histograms, gauges don’t calculate distributions or percentiles.

API Reference

pub struct Gauge<T>(Arc<dyn SyncInstrument<T> + Send + Sync>);

impl<T> Gauge<T> {
    pub fn record(&self, value: T, attributes: &[KeyValue]);
}
The record method sets the current value of the gauge.

Creating a Gauge

Gauges support u64, i64, and f64 data types:
use opentelemetry::global;

let meter = global::meter("my-app");

// u64 gauge
let u64_gauge = meter.u64_gauge("cache_size")
    .with_description("Current cache size in entries")
    .with_unit("{entries}")
    .build();

// i64 gauge (can be negative)
let i64_gauge = meter.i64_gauge("temperature")
    .with_description("Current temperature")
    .with_unit("Cel")
    .build();

// f64 gauge (most common for percentages)
let f64_gauge = meter.f64_gauge("cpu_usage")
    .with_description("Current CPU usage percentage")
    .with_unit("%")
    .build();

Recording Measurements

Use the record method to set the current value:
use opentelemetry::KeyValue;

// Record a simple value
f64_gauge.record(45.2, &[]);

// Record with attributes
f64_gauge.record(
    67.8,
    &[
        KeyValue::new("core", "0"),
        KeyValue::new("host", "server-01"),
    ],
);

// Each call overwrites the previous value for the same attribute set
f64_gauge.record(52.1, &[KeyValue::new("core", "0")]);
Each call to record with the same attribute set overwrites the previous value. Only the last recorded value is exported.

Complete Example

use opentelemetry::{global, KeyValue};
use opentelemetry_sdk::metrics::SdkMeterProvider;
use opentelemetry_sdk::Resource;

fn init_meter_provider() -> SdkMeterProvider {
    let exporter = opentelemetry_stdout::MetricExporterBuilder::default().build();
    let provider = SdkMeterProvider::builder()
        .with_periodic_exporter(exporter)
        .with_resource(
            Resource::builder()
                .with_service_name("my-service")
                .build(),
        )
        .build();
    global::set_meter_provider(provider.clone());
    provider
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let meter_provider = init_meter_provider();
    let meter = global::meter("system-monitor");

    // Create gauges for system metrics
    let cpu_gauge = meter
        .f64_gauge("cpu_usage")
        .with_description("Current CPU usage percentage")
        .with_unit("%")
        .build();

    let memory_gauge = meter
        .u64_gauge("memory_usage")
        .with_description("Current memory usage in bytes")
        .with_unit("By")
        .build();

    let temperature_gauge = meter
        .i64_gauge("cpu_temperature")
        .with_description("Current CPU temperature")
        .with_unit("Cel")
        .build();

    // Record current system state
    cpu_gauge.record(45.2, &[KeyValue::new("core", "0")]);
    cpu_gauge.record(52.1, &[KeyValue::new("core", "1")]);

    memory_gauge.record(1024 * 1024 * 512, &[]);

    temperature_gauge.record(65, &[KeyValue::new("sensor", "cpu0")]);

    meter_provider.shutdown()?;
    Ok(())
}

Example from Source

From the metrics-basic example:
// Create a Gauge Instrument
let gauge = meter
    .f64_gauge("my_gauge")
    .with_description("A gauge set to 1.0")
    .with_unit("myunit")
    .build();

gauge.record(
    1.0,
    &[
        KeyValue::new("mykey1", "myvalue1"),
        KeyValue::new("mykey2", "myvalue2"),
    ],
);

Gauge Types

Choose the appropriate numeric type:

u64 Gauge

For non-negative integers:
let cache_size = meter.u64_gauge("cache_entries").build();
cache_size.record(1500, &[]);

let queue_depth = meter.u64_gauge("queue_depth").build();
queue_depth.record(42, &[]);

i64 Gauge

For integers that can be negative:
let temperature = meter.i64_gauge("temperature").with_unit("Cel").build();
temperature.record(-15, &[KeyValue::new("location", "freezer")]);

let balance = meter.i64_gauge("account_balance").build();
balance.record(-250, &[]);

f64 Gauge

For floating-point values (most common):
let cpu_usage = meter.f64_gauge("cpu_usage").with_unit("%").build();
cpu_usage.record(67.8, &[]);

let voltage = meter.f64_gauge("voltage").with_unit("V").build();
voltage.record(3.3, &[KeyValue::new("rail", "vcc")]);

Gauge vs. ObservableGauge

Choose based on when you record measurements:
// Use when you control when to record
let gauge = meter.f64_gauge("cpu_usage").build();

loop {
    let usage = calculate_cpu_usage();
    gauge.record(usage, &[]);
    thread::sleep(Duration::from_secs(1));
}
See Observable Instruments for more on asynchronous gauges.

Attributes and Cardinality

Gauges support attributes to track multiple related measurements:
let cpu_gauge = meter.f64_gauge("cpu_usage").build();

// Different CPU cores
cpu_gauge.record(45.2, &[KeyValue::new("core", "0")]);
cpu_gauge.record(52.1, &[KeyValue::new("core", "1")]);
cpu_gauge.record(38.7, &[KeyValue::new("core", "2")]);
cpu_gauge.record(61.3, &[KeyValue::new("core", "3")]);
Each unique attribute combination creates a separate gauge value. Keep cardinality reasonable to avoid memory issues.

Cloning Gauges

Gauges can be cloned to share across your application:
let gauge = meter.f64_gauge("temperature").build();
let gauge_clone = gauge.clone();

// Both record to the same underlying gauge
gauge.record(22.5, &[]);
gauge_clone.record(23.1, &[]);  // Overwrites previous value
Clone gauges when sharing across modules. Avoid creating multiple gauges with the same name.

Gauge vs. Histogram

Understand when to use each:
// Only the last value matters
let gauge = meter.f64_gauge("cpu_usage").build();
gauge.record(45.2, &[]);
gauge.record(67.8, &[]);
gauge.record(52.1, &[]);
// Exported: 52.1

Gauge vs. UpDownCounter

Different use cases:
// Records current value, not changes
let gauge = meter.i64_gauge("queue_depth").build();
gauge.record(10, &[]);  // Queue has 10 items
gauge.record(15, &[]);  // Queue now has 15 items

Common Use Cases

System Metrics

let cpu = meter.f64_gauge("system_cpu_usage").with_unit("%").build();
let memory = meter.u64_gauge("system_memory_used").with_unit("By").build();
let disk = meter.u64_gauge("disk_space_available").with_unit("By").build();

cpu.record(67.8, &[]);
memory.record(8589934592, &[]);  // 8 GB in bytes
disk.record(107374182400, &[]);  // 100 GB in bytes

Application Metrics

let connections = meter.u64_gauge("active_connections").build();
let cache_size = meter.u64_gauge("cache_size").with_unit("{entries}").build();
let pool_size = meter.u64_gauge("thread_pool_size").with_unit("{threads}").build();

connections.record(42, &[]);
cache_size.record(1500, &[]);
pool_size.record(10, &[]);

Environmental Sensors

let temp = meter.f64_gauge("temperature").with_unit("Cel").build();
let humidity = meter.f64_gauge("humidity").with_unit("%").build();
let pressure = meter.f64_gauge("pressure").with_unit("hPa").build();

temp.record(22.5, &[KeyValue::new("location", "server_room")]);
humidity.record(45.0, &[KeyValue::new("location", "server_room")]);
pressure.record(1013.25, &[KeyValue::new("location", "server_room")]);

Best Practices

  1. Use for current state: Gauges are for “what is the value now”
  2. Choose the right type: Use f64 for percentages and decimals, u64 for counts, i64 when negative values are possible
  3. Specify units: Use standard units like "%", "By", "Cel", "{entries}"
  4. Keep cardinality low: Limit unique attribute combinations
  5. Clone, don’t duplicate: Share gauges by cloning, not recreating
  6. Consider ObservableGauge: Use callbacks when reading from external sources

Next Steps

Counter

Record monotonically increasing values

Histogram

Record value distributions

Observable Instruments

Use ObservableGauge with callbacks

Views

Customize gauge aggregation

Build docs developers (and LLMs) love