> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Best Practice

> Best practices for naming and instrumenting metrics for Prometheus, covering naming conventions, units, suffixes, and instrumentation guidance for online, offline, and batch systems.

In this lesson we'll cover best practices for naming and instrumenting metrics so they are predictable, unambiguous, and easy to consume with Prometheus and other monitoring tools.

## Metric naming conventions

* Use snake\_case for metric names: lowercase words separated by underscores (for example `http_request_total`).
* Prefix metric names with the application or library name to indicate ownership (for example `postgres_` for Postgres-related metrics).
* Always include the unit in the metric name (use base units such as `seconds`, `bytes`, `meters`) rather than prefixed units (`milliseconds`, `kilobytes`).
* Rely on client libraries to produce type-specific suffixes. Counters should end with `_total`; do not manually add `_sum`, `_bucket`, or `_count` for histograms/summaries — client libraries export those.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/EOkHqyG4hdv97La7/images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/metrics-naming-guidelines-snakecase.jpg?fit=max&auto=format&n=EOkHqyG4hdv97La7&q=85&s=006b80ca9e4a139dc1a3d39565469430" alt="The image provides guidelines for naming metrics, specifying the use of snake_case, and emphasizing that metrics should start with the application/library name." width="1920" height="1080" data-path="images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/metrics-naming-guidelines-snakecase.jpg" />
</Frame>

For example, metrics related to Postgres should begin with `postgres_`, e.g. `postgres_connection_errors`. After the prefix, use descriptive words (e.g., `queue_size`) and append the unit where applicable (e.g., `_seconds`, `_bytes`).

Units avoid ambiguity about scale (is latency in seconds or milliseconds?). Prometheus client libraries and conventions prefer base units (seconds, bytes).

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/EOkHqyG4hdv97La7/images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/naming-metrics-guidelines-units-structure.jpg?fit=max&auto=format&n=EOkHqyG4hdv97La7&q=85&s=a970cd0416e545a44983e74597c513db" alt="The image provides guidelines on naming metrics, emphasizing the inclusion of units like seconds and bytes, using a structure like library_name_unit_suffix." width="1920" height="1080" data-path="images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/naming-metrics-guidelines-units-structure.jpg" />
</Frame>

<Callout icon="lightbulb" color="#1CB2FE">
  Counters must end with `_total`. Do not manually add `_sum`, `_bucket`, or `_count` — those are created by client libraries for histogram/summary metric types.
</Callout>

Common recommended structure:

* `<library>_<metric_name>_<unit>_<optional_suffix>`

Good examples:

```text theme={null}
process_cpu_seconds
http_requests_total
redis_connection_errors
node_disk_read_bytes_total
```

Bad examples and why they are problematic:

```text theme={null}
container_docker_restarts        # library should be 'docker' prefix: docker_container_restarts
http_requests_sum                # don't put 'sum' in name — summaries/histograms export _sum automatically
nginx_disk_free_kilobytes        # use base units: bytes, not kilobytes
dotnet_queue_waiting_time        # missing units: append '_seconds'
```

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/EOkHqyG4hdv97La7/images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/metric-names-comparison-proper-incorrect.jpg?fit=max&auto=format&n=EOkHqyG4hdv97La7&q=85&s=2466e96738ce1e08e7c1833cf3962681" alt="The image shows a comparison of proper and incorrect metric names, with examples such as &#x22;process_cpu_seconds&#x22; and &#x22;http_requests_total&#x22; being proper, and &#x22;container_docker_restarts&#x22; and &#x22;http_requests_sum&#x22; being incorrect." width="1920" height="1080" data-path="images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/metric-names-comparison-proper-incorrect.jpg" />
</Frame>

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/EOkHqyG4hdv97La7/images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/metric-naming-conventions-examples.jpg?fit=max&auto=format&n=EOkHqyG4hdv97La7&q=85&s=6287e48134eef879dfa92cf535fd6924" alt="The image lists naming conventions for metrics, categorizing them into &#x22;Proper Metric Names&#x22; and &#x22;Incorrect Metric Names&#x22; with examples for each category." width="1920" height="1080" data-path="images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/metric-naming-conventions-examples.jpg" />
</Frame>

### Common suffixes and metric types

| Suffix    | Metric type       | Notes                                                                   |
| --------- | ----------------- | ----------------------------------------------------------------------- |
| `_total`  | Counter           | Cumulative counter value. Use this for monotonically increasing counts. |
| `_count`  | Histogram/Summary | Auto-generated by client libraries for count of observations.           |
| `_sum`    | Histogram/Summary | Auto-generated by client libraries for the sum of observed values.      |
| `_bucket` | Histogram         | Auto-generated by client libraries for histogram buckets.               |

For more details on conventions, see the Prometheus best practices and instrumentation guides:

* [Prometheus documentation: Instrumentation](https://prometheus.io/docs/practices/instrumentation/)
* [Prometheus: Naming and labels](https://prometheus.io/docs/practices/naming/)

## What to instrument

Decide which metrics to collect based on the nature of your application. The three common categories and recommended metrics are:

### 1) Online serving systems

Online systems expect immediate responses (databases, web servers, APIs). Instrument the following:

* Total number of requests/queries (`*_total`)
* Error counts (`*_errors_total`)
* Request latency (`*_seconds`, often as histograms or summaries)
* Number of in-progress requests (gauge)

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/EOkHqyG4hdv97La7/images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/online-serving-systems-metrics-response-time.jpg?fit=max&auto=format&n=EOkHqyG4hdv97La7&q=85&s=362e5013a66569f203a47ed342c7b720" alt="The image is a slide about online-serving systems, highlighting the expectation of immediate responses and including metrics like the number of queries, errors, latency, and ongoing requests." width="1920" height="1080" data-path="images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/online-serving-systems-metrics-response-time.jpg" />
</Frame>

Suggested metrics for an HTTP server:

```text theme={null}
http_requests_total
http_requests_duration_seconds_bucket  # histogram buckets (auto-generated)
http_requests_inprogress  # gauge
http_request_errors_total
```

### 2) Offline processing services

These are long-running background systems with multiple stages. Instrument per-stage and pipeline-level metrics:

* Amount of work processed (counter)
* Queue/backlog size (gauge)
* Work in progress (gauge)
* Processing rate (derived from counters)
* Errors per stage

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/EOkHqyG4hdv97La7/images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/offline-processing-services-explained.jpg?fit=max&auto=format&n=EOkHqyG4hdv97La7&q=85&s=cd60fdcc4f1c4a800cf714a787d9e776" alt="The image explains offline processing services, noting they're not actively monitored, and stages involve measuring queued work, work in progress, and processing rate." width="1920" height="1080" data-path="images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/offline-processing-services-explained.jpg" />
</Frame>

Example per-stage metrics:

```text theme={null}
worker_stage_items_processed_total
worker_stage_processing_seconds_sum
worker_stage_processing_seconds_count
worker_stage_queue_size
```

### 3) Batch jobs

Batch jobs run on a schedule and are often short-lived. Because Prometheus may not scrape short-lived processes, use a Pushgateway for job-level metrics that must be retained until scraped.

Instrument the following for batch jobs:

* Per-stage processing time (`_seconds`)
* Overall job runtime (`_seconds`)
* Success and failure counts (`myjob_success_total`, `myjob_failure_total`)
* Number of items processed (`*_processed_total`)
* Backlog/queued items before start

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/EOkHqyG4hdv97La7/images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/batch-jobs-offline-serving-differences.jpg?fit=max&auto=format&n=EOkHqyG4hdv97La7&q=85&s=00dc8f88f17f1b017c5d68d1be9c7f80" alt="The image describes the differences between batch jobs and offline-serving systems, noting that batch jobs run on a regular schedule while offline systems run continuously, and mentions the need for a pushGateway for non-continuous tasks." width="1920" height="1080" data-path="images/Prep-Course-Prometheus-Certified-Associate-PCA-Certification/Application-Instrumentation/Best-Practice/batch-jobs-offline-serving-differences.jpg" />
</Frame>

<Callout icon="warning" color="#FF6B6B">
  When using a Pushgateway, label pushed metrics clearly (e.g., `job` and instance identifier). Do not use the Pushgateway for ephemeral per-request metrics — it's intended for short-lived batch jobs and service-level metrics.
</Callout>

## Practical tips

* Keep metric names consistent across services to simplify querying and alerting.
* Use labels for dimensions (e.g., `method`, `status_code`, `region`) instead of encoding dimensions into metric names.
* Prefer histograms for latency distributions and counters for cumulative counts.
* Document your metrics (what they measure, units, and labels) so consumers and SREs can use them correctly.

## References

* [Prometheus: Instrumentation best practices](https://prometheus.io/docs/practices/instrumentation/)
* [Prometheus: Naming guidelines](https://prometheus.io/docs/practices/naming/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/prometheus-certified-associate-pca/module/0c0155c7-00c8-4ca2-a061-e66baa1a3216/lesson/fcbaaf76-5012-4da6-8ded-16ed04813936" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/prometheus-certified-associate-pca/module/0c0155c7-00c8-4ca2-a061-e66baa1a3216/lesson/9822084e-5e32-4e25-89ef-335fce5cc0f8" />
</CardGroup>
