Skip to content

Pull vs push: Prometheus and OTel

The toolkit gives you two metrics families, and they are deliberately different. transport-metrics is the Prometheus, pull/scrape one; go/observability is the OTel, push one. This page explains why both exist and how to choose — or combine — them.

Two models

go/transport-metrics (this) go/observability (OTel)
Collection pull — a scraper fetches GET /metrics push — the app sends OTLP to a collector
Infra to use none — curl/scrape locally an OTLP collector/endpoint
Format Prometheus text / OpenMetrics OTLP
Sweet spot local + single-binary tools; classic Prometheus/Grafana stacks fleets with a collector pipeline; unified traces+metrics+logs
Trace link OpenMetrics exemplars (Phase 2) OTel-native span context

Why not just one

The work that seeded this module was a single-binary tool whose author wanted to watch its memory live and catch a leak — no Kubernetes, no collector, no OTLP endpoint to stand up. For that, pull is right: expose /metrics, point curl/prometheus/pprof at it, done. Requiring an OTLP collector for a single-user local tool is disproportionate.

Conversely, a fleet already shipping OTLP wants its metrics in the same pipeline as its traces and logs. For that, go/observability's push model is right.

Neither subsumes the other; forcing one model on both use cases makes one of them worse. So the toolkit ships both, clearly labelled.

Using both

They do not conflict — distinct modules, distinct package names, no shared global state. transport-metrics owns its own private *prometheus.Registry; go/observability owns the OTel meter. A tool can run OTLP push in production and expose a loopback /metrics + pprof for local debugging, with no interference.

The exemplar bridge (Phase 2)

The one place the two worlds meet is exemplars: an OpenMetrics exemplar attaches a trace id to a metric sample, so a latency spike on a Prometheus dashboard links to the exact trace. Phase 2 reads that trace id through a pluggable source, so the core needs no OTel dependency and the bridge stays opt-in — complementing go/observability, never competing with it.