Metric and label naming conventions

Prometheus · Essentials · 8 min

Consistent names let anyone guess a metric and its unit, and PromQL functions assume the conventions.

Prometheus does not enforce naming, but the ecosystem relies on a few conventions, and tools such as Grafana, promtool check metrics and the client libraries assume them.

A metric name has three parts: a prefix for the application or subsystem (http_, node_, myapp_), a description of what is measured, and a unit suffix. Use snake_case.

  • Always use base units: _seconds (not milliseconds), _bytes (not megabytes), _ratio for 0 to 1 values (not percent), _celsius, _joules. Converting is the dashboard's job; mixed units in one query are a classic bug.
  • Counters end in _total: http_requests_total. Histograms and summaries get _bucket, _sum and _count added automatically, so the base name is just http_request_duration_seconds.
  • A metric should mean the same thing across all its label values. Don't put bytes sent and bytes received under one name with a direction label unless summing them makes sense; do use labels for dimensions you will aggregate over.
  • Info metrics carry labels and the constant value 1: app_build_info{version="2.3.1", go_version="1.24"}. Join them onto other series when you need the labels.
  • Don't repeat labels in the name: http_requests_get_total should be http_requests_total{method="GET"}.

Label names are snake_case too; job, instance and the __ prefix are reserved. Since Prometheus 3.0 any UTF-8 string is technically allowed in names (useful for OpenTelemetry data), but the conventions above are still what everyone expects.

Example

# Good
http_requests_total{method="GET",code="200"}      # counter, _total
http_request_duration_seconds_bucket{le="0.25"}   # histogram in seconds
process_resident_memory_bytes                      # gauge in bytes
queue_backlog_ratio                                # 0..1, not percent
myapp_build_info{version="2.3.1"} 1                # info metric

# Bad
requestsGET                       # no prefix, label baked into the name
http_latency_ms                   # not a base unit
cpu_percent                       # use a ratio and multiply by 100 in Grafana
errors                            # counter without _total, no namespace

# promtool can lint an exposition page:
# curl -s localhost:8000/metrics | promtool check metrics

Remember

  • prefix + what + base unit, in snake_case
  • Counters end in _total; histograms get _bucket/_sum/_count for free
  • Dimensions go in labels, not in the name; info metrics have value 1

Watch out for

  • Exposing latency in milliseconds alongside other metrics in seconds, then mixing them in one query.

Check yourself

  1. Which name best follows the conventions for a counter of bytes written to disk by a backup tool?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: prometheus.io/docs/practices/naming/

Builds on

Unlocks

Nothing builds on this yet.