Naming Conventions
Metric and Label Naming Conventions
Metric Names
Basic Rules
According to the official Prometheus documentation, a metric name:c name:
MUST:
- Comply with the data model for allowed characters:
[a-zA-Z_:][a-zA-Z0-9_:]* - Have a single unit (don’t mix seconds with milliseconds or seconds with bytes)
SHOULD:
- Have an application prefix appropriate for the domain (single word):
prometheus_notifications_total(specific to Prometheus server)process_cpu_seconds_total(exported by many client libraries)http_request_duration_seconds(for all HTTP requests)
- Use base units (seconds, bytes, meters - not milliseconds, megabytes, kilometers)
- Have a suffix describing the unit in plural:
http_request_duration_secondsnode_memory_usage_byteshttp_requests_total(for counter without unit)process_cpu_seconds_total(counter with unit)foobar_build_info(pseudo-metric with metadata)
MAY:
- Order name components for convenient alphabetical grouping:
prometheus_tsdb_head_truncations_closed_total prometheus_tsdb_head_truncations_established_total prometheus_tsdb_head_truncations_failed_total prometheus_tsdb_head_truncations_total
SHOULD:
- Represent the same logical “what is being measured” across all label dimensions
- Make sense when aggregating with
sum()oravg()across all dimensions
Why include units and types in names?
Prometheus strongly recommends including unit and type in metric name for practical reasons:
- Reliability and user experience: In YAML configuration (alerts, rules, dashboards) it’s crucial to understand metric type and unit at first glance
- Metric collisions: Lack of unit information can lead to collisions (e.g.,
process_cpufor seconds vs milliseconds)
Labels
Basic rules
Use labels to differentiate characteristics of what is being measured:
api_http_requests_total- differentiate request types:operation="create|update|delete"api_request_duration_seconds- differentiate stages:stage="extract|transform|load"
What to avoid
- Don’t put label names in metric name - introduces repetition and confusion during aggregation
- Don’t use high cardinality labels (user IDs, email addresses) - dramatically increases amount of stored data
NOTE: Each unique combination of label key-value pairs represents a new time series!
Base units
Prometheus doesn’t have built-in units. For better compatibility, use base units:
| Category | Base unit | Notes |
|---|---|---|
| Time | seconds |
|
| Temperature | celsius |
Preferred over kelvin for practical reasons |
| Length | meters |
|
| Data | bytes |
|
| Bits | bytes |
Always bytes to avoid confusion |
| Percentages | ratio |
Values 0-1 (not 0-100). Suffix only for names like disk_usage_ratio |
| Voltage | volts |
|
| Current | amperes |
|
| Energy | joules |
|
| Power | - | Prefer exporting joule counter, then rate(joules[5m]) gives power in watts |
| Mass | grams |
Preferred over kilograms to avoid problems with kilo prefix |
Good naming examples
# Counters
http_requests_total{method="GET", status="200"}
database_queries_total{operation="SELECT"}
# Gauges
memory_usage_bytes
cpu_usage_ratio
queue_size
# Histograms
http_request_duration_seconds
response_size_bytes
# With time units
process_cpu_seconds_total
gc_duration_seconds
Bad naming examples
# Missing units
request_duration # should be request_duration_seconds
memory_usage # should be memory_usage_bytes
# Mixed units
latency_ms # should be latency_seconds
storage_mb # should be storage_bytes
# Repeating labels in name
http_requests_method_total # method should be a label