> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/open-telemetry/opentelemetry-rust/llms.txt
> Use this file to discover all available pages before exploring further.

# Gauge

> Record independent point-in-time values with Gauge instruments in OpenTelemetry Rust

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

<Note>
  Gauges record point-in-time values. The last value recorded is what gets exported. Unlike histograms, gauges don't calculate distributions or percentiles.
</Note>

## API Reference

```rust theme={null}
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:

```rust theme={null}
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:

```rust theme={null}
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")]);
```

<Warning>
  Each call to `record` with the same attribute set overwrites the previous value. Only the last recorded value is exported.
</Warning>

## Complete Example

```rust theme={null}
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:

```rust theme={null}
// 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:

```rust theme={null}
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:

```rust theme={null}
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):

```rust theme={null}
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:

<CodeGroup>
  ```rust Gauge (Synchronous) theme={null}
  // 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));
  }
  ```

  ```rust ObservableGauge (Asynchronous) theme={null}
  // Use when reading from external sources
  let _observable_gauge = meter
      .f64_observable_gauge("cpu_usage")
      .with_callback(|observer| {
          let usage = read_from_system_api();
          observer.observe(usage, &[]);
      })
      .build();
  // SDK calls callback automatically during collection
  ```
</CodeGroup>

See [Observable Instruments](/metrics/observable-instruments) for more on asynchronous gauges.

## Attributes and Cardinality

Gauges support attributes to track multiple related measurements:

```rust theme={null}
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")]);
```

<Warning>
  Each unique attribute combination creates a separate gauge value. Keep cardinality reasonable to avoid memory issues.
</Warning>

## Cloning Gauges

Gauges can be cloned to share across your application:

```rust theme={null}
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
```

<Tip>
  Clone gauges when sharing across modules. Avoid creating multiple gauges with the same name.
</Tip>

## Gauge vs. Histogram

Understand when to use each:

<CodeGroup>
  ```rust Gauge - Last Value theme={null}
  // 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
  ```

  ```rust Histogram - Distribution theme={null}
  // All values are important for statistics
  let histogram = meter.f64_histogram("request_duration").build();
  histogram.record(0.123, &[]);
  histogram.record(0.456, &[]);
  histogram.record(0.789, &[]);
  // Exported: min, max, p50, p95, p99, count, sum
  ```
</CodeGroup>

## Gauge vs. UpDownCounter

Different use cases:

<CodeGroup>
  ```rust Gauge - Current State theme={null}
  // 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
  ```

  ```rust UpDownCounter - Changes theme={null}
  // Records changes (deltas)
  let counter = meter.i64_up_down_counter("queue_depth").build();
  counter.add(10, &[]);   // Added 10 items
  counter.add(5, &[]);    // Added 5 more items
  counter.add(-3, &[]);   // Removed 3 items
  // Cumulative: 10 + 5 - 3 = 12
  ```
</CodeGroup>

## Common Use Cases

### System Metrics

```rust theme={null}
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

```rust theme={null}
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

```rust theme={null}
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

<CardGroup cols={2}>
  <Card title="Counter" href="/metrics/counter">
    Record monotonically increasing values
  </Card>

  <Card title="Histogram" href="/metrics/histogram">
    Record value distributions
  </Card>

  <Card title="Observable Instruments" href="/metrics/observable-instruments">
    Use ObservableGauge with callbacks
  </Card>

  <Card title="Views" href="/metrics/views">
    Customize gauge aggregation
  </Card>
</CardGroup>
