Skip to main content
A counter is a cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero on restart.

When to use counters

Use counters to track:
  • Total number of HTTP requests served
  • Total number of tasks completed
  • Total number of errors
  • Total bytes sent or received
Do not use a counter to expose a value that can decrease. For example, do not use a counter for the number of currently running processes; instead use a gauge.

Creating a counter

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

create_counter(
  registry: "default",
  name: "http_requests_total",
  help: "Total number of HTTP requests",
  labels: ["method", "route", "status"],
)

Parameters

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

Incrementing a counter

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

increment_counter(
  registry: "default",
  name: "http_requests_total",
  labels: ["GET", "/", "200"],
  value: 1,
)

Parameters

  • registry: The registry name (must match the one used when creating the counter)
  • name: The metric name (must match the one used when creating the counter)
  • labels: Label values in the same order as the label names
  • value: The amount to increment (must be a positive integer)
The number of label values must match the number of label names defined when creating the counter. 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 counter to track HTTP requests:
import promgleam/metrics/counter.{create_counter, increment_counter}

pub fn setup_metrics() {
  // Create the counter once during application startup
  let assert Ok(Nil) = create_counter(
    registry: "default",
    name: "http_requests_total",
    help: "Total number of HTTP requests",
    labels: ["method", "route", "status"],
  )
}

pub fn handle_request(method: String, route: String) {
  // Your request handling logic here
  let status = "200"
  
  // Increment the counter after processing the request
  let assert Ok(Nil) = increment_counter(
    registry: "default",
    name: "http_requests_total",
    labels: [method, route, status],
    value: 1,
  )
}

Error handling

Both create_counter and increment_counter return a Result type. Here are common errors you might encounter:
When trying to create a counter that already exists:
case create_counter(
  registry: "default",
  name: "http_requests_total",
  help: "Total number of HTTP requests",
  labels: ["method"],
) {
  Ok(Nil) -> io.println("Counter created successfully")
  Error(msg) -> io.println("Error: " <> msg)
  // Error: Metric already exists
}

Best practices

1

Create counters once

Create your counters during application initialization, not on every request.
2

Use descriptive names

Always end counter names with _total and make them descriptive: http_requests_total, errors_total, bytes_sent_total.
3

Keep labels consistent

Always provide label values in the same order as defined when creating the counter.
4

Avoid high cardinality

Don’t use unique values (like user IDs or timestamps) as label values, as this creates too many time series.
Most counters should be incremented by 1, but you can increment by larger values when tracking things like bytes transferred or batch operations.

Build docs developers (and LLMs) love