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.
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
/metricsendpoints 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:
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:
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:
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:
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
- Operator Lifecycle Manager OLM vs Helm
- Optimal JVM settings for Cassandra
- Optional map variables in terraform module
- Options for deploying R models in production
- ONM time complexity
- onnxruntime inference is way slower than pytorch on GPU
- org.ops4j.pax.logging.pax-logging-api [log4j2] ERROR
- Pass args to the Dockerfile from docker-compose

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack 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.