Skip to main content
A gauge is a metric that represents a single numerical value that can arbitrarily go up and down. Gauges are typically used for measured values like temperatures or current memory usage, but also “counts” that can go up and down, like the number of concurrent requests.

When to use gauges

Use gauges to track:
  • Current memory usage
  • Number of concurrent requests
  • Cache size
  • Temperature readings
  • Queue length
  • Number of active connections
Unlike counters, gauges can both increase and decrease. If your metric only increases, use a counter instead.

Creating a gauge

Use the create_gauge function to create a new gauge metric. You need to specify the registry name, metric name, help text, and label names.
import promgleam/metrics/gauge.{create_gauge}

create_gauge(
  registry: "default",
  name: "cache_size",
  help: "Number of items in the cache",
  labels: ["cache_name"],
)

Parameters

  • registry: The name of the registry to register the metric in (commonly "default")
  • name: The metric name (should describe what is being measured)
  • help: A description of what the metric measures
  • labels: A list of label names for this metric
The create_gauge function returns Result(Nil, String). If the metric already exists, you’ll get an error.

Setting a gauge value

Once you’ve created a gauge, use the set_gauge function to set its current value. You must provide label values that match the label names defined when creating the gauge.
import promgleam/metrics/gauge.{set_gauge}

set_gauge(
  registry: "default",
  name: "cache_size",
  labels: ["image_cache"],
  value: 123,
)

Parameters

  • registry: The registry name (must match the one used when creating the gauge)
  • name: The metric name (must match the one used when creating the gauge)
  • labels: Label values in the same order as the label names
  • value: The current value to set (can be any integer)
The number of label values must match the number of label names defined when creating the gauge. If they don’t match, you’ll get an InvalidMetricArity error.

Complete example

Here’s a complete example showing how to create and use a gauge to track cache size:
import promgleam/metrics/gauge.{create_gauge, set_gauge}
import gleam/dict.{type Dict}

pub type Cache {
  Cache(items: Dict(String, String))
}

pub fn setup_metrics() {
  // Create the gauge once during application startup
  let assert Ok(Nil) = create_gauge(
    registry: "default",
    name: "cache_size",
    help: "Number of items in the cache",
    labels: ["cache_name"],
  )
}

pub fn add_to_cache(cache: Cache, key: String, value: String) -> Cache {
  let new_cache = Cache(dict.insert(cache.items, key, value))
  
  // Update the gauge to reflect the current cache size
  let cache_size = dict.size(new_cache.items)
  let assert Ok(Nil) = set_gauge(
    registry: "default",
    name: "cache_size",
    labels: ["main_cache"],
    value: cache_size,
  )
  
  new_cache
}

pub fn remove_from_cache(cache: Cache, key: String) -> Cache {
  let new_cache = Cache(dict.delete(cache.items, key))
  
  // Update the gauge to reflect the current cache size
  let cache_size = dict.size(new_cache.items)
  let assert Ok(Nil) = set_gauge(
    registry: "default",
    name: "cache_size",
    labels: ["main_cache"],
    value: cache_size,
  )
  
  new_cache
}

Error handling

Both create_gauge and set_gauge return a Result type. Here are common errors you might encounter:
When trying to create a gauge that already exists:
case create_gauge(
  registry: "default",
  name: "cache_size",
  help: "Number of items in the cache",
  labels: ["cache_name"],
) {
  Ok(Nil) -> io.println("Gauge created successfully")
  Error(msg) -> io.println("Error: " <> msg)
  // Error: Metric already exists
}

Tracking concurrent operations

Gauges are commonly used to track the number of concurrent operations. Here’s an example:
import promgleam/metrics/gauge.{create_gauge, set_gauge}

pub fn setup_metrics() {
  let assert Ok(Nil) = create_gauge(
    registry: "default",
    name: "active_requests",
    help: "Number of requests currently being processed",
    labels: [],
  )
}

pub fn handle_request(request_handler: fn() -> response, current_active: Int) {
  // Increment the gauge when starting
  let new_active = current_active + 1
  let assert Ok(Nil) = set_gauge(
    registry: "default",
    name: "active_requests",
    labels: [],
    value: new_active,
  )
  
  // Process the request
  let response = request_handler()
  
  // Decrement the gauge when done
  let final_active = new_active - 1
  let assert Ok(Nil) = set_gauge(
    registry: "default",
    name: "active_requests",
    labels: [],
    value: final_active,
  )
  
  response
}
For tracking concurrent operations, you need to maintain the current count in your application state and update the gauge whenever it changes.

Best practices

1

Create gauges once

Create your gauges during application initialization, not every time you need to update them.
2

Use descriptive names

Make gauge names descriptive: memory_usage_bytes, active_connections, queue_length.
3

Set the actual value

Always set the gauge to the current absolute value, not a delta. Gauges represent the current state.
4

Include units

Include the unit in the metric name when applicable: _bytes, _seconds, _celsius.

Gauges vs counters

Use a counter when the value only increases (or resets to zero).Use a gauge when the value can both increase and decrease.
MetricTypeReason
Total HTTP requestsCounterOnly increases
Active connectionsGaugeCan increase and decrease
Memory usageGaugeCan increase and decrease
Total errorsCounterOnly increases
Queue lengthGaugeCan increase and decrease

Build docs developers (and LLMs) love