Prometheus Metrics
Service Monitoring
Observability
System Performance
Data Exposure

Only expose promethues metrics once per service

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Exposing Prometheus metrics exactly once per service is important for clean cardinality, accurate dashboards, and avoiding duplicate time series. Duplicate exposure usually happens when multiple app instances export identical labels behind one scrape target, or when both sidecar and app endpoints publish overlapping metrics. The goal is not to reduce replicas, but to design scrape configuration and metric labeling so each logical signal is represented once per intended dimension. This article outlines practical strategies for avoiding duplicate metrics in service-level monitoring.

Core Sections

1. Understand duplication sources

Common duplication patterns:

  • multiple /metrics endpoints scraped for same component
  • duplicated exporters (app + sidecar) emitting same metric names
  • scraping per-pod while dashboard expects per-service aggregate
  • missing distinguishing labels (pod, instance, job)

Identify whether duplication is collection-side or query-side first.

2. Choose one canonical metrics endpoint

If both application and sidecar expose overlapping metrics, decide ownership:

  • app endpoint for business metrics
  • sidecar/exporter for infrastructure metrics

Do not expose same metric family from both.

Kubernetes ServiceMonitor example:

yaml
endpoints:
  - port: http-metrics
    path: /metrics

Ensure only one endpoint is configured for the logical signal.

3. Use query aggregation intentionally

If per-pod metrics are expected, aggregate to service-level in PromQL:

promql
sum by (service) (http_requests_total{job="my-service"})

Do not interpret raw per-instance series as duplicates when they represent replicas.

4. Avoid duplicate registration in code

In-process duplication can occur if metrics are registered multiple times during app startup/reload.

Python example with singleton registry usage:

python
from prometheus_client import Counter

REQUESTS = Counter("my_requests_total", "Total requests")

Guard against creating the same metric object in request handlers.

5. Relabeling and target hygiene

Use relabel configs to drop unintended targets and keep label cardinality controlled. Ensure scrape jobs do not overlap same endpoint through multiple discovery rules.

6. Validation workflow

Validate in Prometheus UI:

promql
count by (job, instance, pod) (up{job="my-service"})

Then inspect one metric family for unexpected identical labelsets. Add CI checks for ServiceMonitor duplication in Kubernetes manifests.

Validation and production readiness

A reliable implementation is not complete until it is validated under realistic conditions. Add a minimal but representative test matrix that includes normal inputs, edge cases, and malformed data. For UI-focused topics, include at least one scenario for lifecycle or timing behavior (initial load, state transition, and cleanup) so regressions are detected when framework versions change. For infrastructure and tooling topics, run commands against a disposable environment before applying in production and capture expected outputs in documentation. This reduces ambiguity when teammates reproduce steps later.

Instrumentation is equally important. Add structured logs around the critical path, including input shape, selected branch decisions, and failure reasons. Keep logs concise and machine-parseable so alerts and dashboards can surface patterns quickly. If operations are expensive or remote (network, filesystem, container orchestration), include timeout handling and explicit retry policy with backoff. Silent retries without bounds are a common source of hidden incidents.

Finally, document assumptions and compatibility boundaries near the code or article examples: runtime versions, platform requirements, and known behavior differences across environments. Add a lightweight checklist for rollouts that covers dependency pinning, backup/rollback strategy, and smoke checks after deployment. Teams that treat these steps as part of the baseline implementation, not optional polish, usually see fewer production surprises and faster recovery when issues occur.

Common Pitfalls

  • Scraping the same endpoint from multiple jobs unintentionally.
  • Emitting identical metric names from both app and sidecar exporters.
  • Misreading replica-level metrics as duplicates instead of intended dimensions.
  • Registering metric objects multiple times in application lifecycle.
  • Skipping relabel rules and accumulating noisy or overlapping targets.

Summary

To expose Prometheus metrics once per service, separate metric ownership clearly, avoid overlapping scrape targets, and aggregate intentionally in queries. Duplicate time series are usually a scrape-design or instrumentation-lifecycle issue. With canonical endpoints, clean labels, and validation queries, monitoring stays accurate and maintainable at scale.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.