OpenMetrics, Prometheus, and OpenTelemetry: how they fit together
Prometheus is the monitoring system, OpenMetrics is the metrics exposition contract, and OpenTelemetry is the instrumentation and pipeline layer.
Prometheus is familiar. A service exposes /metrics, Prometheus scrapes it, stores time series, and engineers query it with PromQL.
Then OpenMetrics shows up and the naming gets confusing. Is OpenMetrics a replacement for Prometheus? Is it just a new name for the text format? Is it a protocol, a file format, a standard, or a competing project?
The practical answer is simpler:
Prometheus is the monitoring system.
OpenMetrics is the standard for exposing metrics.
OpenTelemetry is the instrumentation and pipeline ecosystem.
They overlap because they grew from the same operational reality. They are not the same layer.
Prometheus made the model popular
Prometheus is not only a text format. It is a monitoring system: scraping, storage, PromQL, alerting, recording rules, exporters, and a huge ecosystem of conventions around how metrics are produced and consumed.
One reason it spread so well is that the exposition format was easy to work with. A service could expose plain text. Humans could read it. Machines could parse it. Exporters could bridge existing systems without complicated agents.
That format traveled beyond Prometheus itself. Client libraries, exporters, sidecars, managed services, and other tools began speaking a Prometheus-like metrics language because it was simple and useful.
Once a format becomes shared infrastructure, it needs a clearer contract than “whatever Prometheus happens to parse.”
That is where OpenMetrics fits.
OpenMetrics is the contract
OpenMetrics formalizes the ideas that worked in the Prometheus exposition format. It is not trying to replace the Prometheus mental model. It is trying to make the wire format easier for multiple tools to implement consistently.
If Prometheus made the style popular, OpenMetrics tightened the edges.
The familiar shape remains:
# HELP http_requests_total Total HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="GET",code="200"} 42
http_requests_total{method="POST",code="500"} 3
OpenMetrics keeps that family resemblance, but the contract gets more explicit:
# HELP http_request_duration_seconds Request latency.
# TYPE http_request_duration_seconds histogram
# UNIT http_request_duration_seconds seconds
http_request_duration_seconds_bucket{method="GET",le="0.1"} 124 # {trace_id="6f3d9c"} 0.08
http_request_duration_seconds_bucket{method="GET",le="+Inf"} 500
http_request_duration_seconds_sum{method="GET"} 61.7
http_request_duration_seconds_count{method="GET"} 500
# EOF
The differences are not cosmetic. OpenMetrics defines details such as a formal media type, the # EOF marker, units, creation timestamps, exemplars, and additional metric family types.
That matters when many tools are producing and consuming metrics. Standards reduce guessing.
The layers are different
The easiest way to avoid confusion is to separate the layers:
| Layer | Role |
|---|---|
| Prometheus | Scrape, store, query, alert, and operate metrics |
| OpenMetrics | Define how metrics are exposed on the wire |
| OpenTelemetry | Instrument applications and move telemetry through SDKs and Collectors |
Prometheus can scrape metrics. OpenMetrics can describe what the endpoint exposes. OpenTelemetry can produce metrics or move them through a Collector to whatever backend you run.
Those are not enemies. They are different parts of the path.
Why both names still exist
Standards do not erase the system that inspired them.
Prometheus is still the operational model many teams know first. PromQL is still the query language many dashboards and alerts depend on. Exporters and service discovery are still part of how teams run monitoring in production.
OpenMetrics gives the exposition format a neutral, better-specified shape. That helps the ecosystem because producers and consumers can agree on semantics without reverse engineering one implementation.
So both names remain useful:
- Use “Prometheus” when you mean the server, scrape model, PromQL, alerting, or ecosystem.
- Use “OpenMetrics” when you mean the exposition standard.
If the endpoint looks familiar, that is intentional. OpenMetrics is not a foreign object. It is the formalized version of a metrics style Prometheus made mainstream.
Where OpenTelemetry fits
OpenTelemetry is a different layer again. It is not the Prometheus server. It is not only an exposition format.
OpenTelemetry gives applications APIs and SDKs for metrics, logs, and traces. The Collector can receive, process, transform, and export telemetry. It can send metrics to Prometheus-compatible systems, OTLP backends, or other destinations.
In real systems, the layers often combine:
application instrumentation
-> OpenTelemetry SDK
-> OpenTelemetry Collector
-> Prometheus-compatible metrics backend
or:
application exposes OpenMetrics
-> Prometheus scrapes /metrics
-> PromQL dashboards and alerts
The right architecture depends on what produces the metrics and what consumes them. The important thing is to preserve metric meaning across the path: names, labels, units, types, and timestamps.
What this means for integrations
The practical question is not “which brand do we pick?”
The practical question is:
What does the producer expose, and what does the consumer understand?
If a source emits OpenMetrics correctly, that is a strong default because it uses the formal standard.
If a source emits classic Prometheus text, that is still useful in Prometheus-based pipelines.
If your system sits in the middle, your job is to preserve semantics:
| Thing to preserve | Why |
|---|---|
| Metric names | Dashboards and alerts depend on them |
| Labels | They define series identity and query dimensions |
| Units | Latency in seconds and milliseconds are not interchangeable |
| Types | Counters, gauges, and histograms behave differently |
| Exemplars | They link metric points to trace context |
Do not flatten everything into vague counters because text is easy to parse. The shape is the data model.
A basic scrape still looks boring
A simple Prometheus scrape config remains familiar:
scrape_configs:
- job_name: app
static_configs:
- targets: ["app:9464"]
That is part of why the terms blur together. The operational motion looks the same whether the endpoint speaks older Prometheus text or OpenMetrics text.
The difference is the contract at the endpoint.
Conclusion
Prometheus is the system. OpenMetrics is the contract.
Prometheus gave the industry a practical monitoring model that teams actually adopted. OpenMetrics took the exposition format that traveled between tools and made it a standard.
OpenTelemetry sits beside them as the instrumentation and telemetry pipeline layer.
If you keep those layers separate, the naming stops being confusing. You can run Prometheus, expose OpenMetrics, and use OpenTelemetry in the same architecture without contradiction.
That is the useful mental model: they are collaborators in the same metrics ecosystem, not three projects fighting for the same seat.