on
Building a cost-effective long-term metrics pipeline with Prometheus remote_write and Grafana Mimir
Observability often starts small — a single Prometheus scraping a few services, a handful of Grafana panels showing “up” and response time. Growth is neat until the moment you need to retain months of metrics, query across clusters, or keep costs in check while dashboards remain snappy. This article walks through a practical, recent pattern that has become common: keep Prometheus for local scraping and short-term alerting, and use Prometheus’ remote_write to send metrics to Grafana Mimir (or another long-term metrics store) for retention, multi-cluster aggregation, and dashboarding. You’ll get a sense of architecture, tuning knobs, and concrete snippets for Prometheus and Grafana-friendly workflows. (grafana.com)
Why this pattern now
- Prometheus is excellent as a pull-based collector, local to a cluster, but it wasn’t designed as a multi-year, highly-available long-term storage. Forwarding metrics via remote_write decouples collection from long-term storage, letting you scale and replace either side independently. Grafana Mimir is one of the widely-adopted Prometheus-compatible long-term time-series backends that integrates well with Grafana dashboards and Grafana Cloud. (grafana.com)
- There’s increasing alignment between OpenTelemetry and the Prometheus ecosystem: the OpenTelemetry Collector can export metrics into Prometheus-compatible long-term storage (including Mimir), which helps consolidate metric sources without changing instrumentation across teams. (grafana.com)
- Recent improvements in metrics backends (for example architectural updates focused on separating read and write paths) aim to improve reliability and cost-efficiency at scale, making remote_write-based pipelines more robust for production workloads. (grafana.com)
Core components and flow
- Prometheus (or a lightweight Prometheus Agent / Grafana Agent) scrapes instrumented apps and services.
- Prometheus continues to evaluate local recording rules and alerts for fast, local decision-making.
- Prometheus is configured with remote_write to push samples to Mimir (or another endpoint). The remote store handles long-term retention, downsampling/compaction, and cross-cluster querying.
- Grafana connects to the long-term store for dashboards, historical exploration, and multi-tenant views; it may still query local Prometheus for sub-minute alerting or ephemeral needs. (grafana.com)
Key design considerations 1) Preserve alerting responsiveness locally
- Keep a small, local Prometheus per cluster that evaluates alerts against freshly scraped data. Remote_write introduces latency and is not a replacement for real-time alerting. Configure Alertmanager locally or with routing that prefers the local instance.
2) Control cardinality before it leaves your cluster
- Cardinality is the primary cost and performance driver. Use relabeling in scrape_configs and remote_write, and apply recording rules for expensive queries at the Prometheus side so fewer high-cardinality series are shipped and stored. The Prometheus remote_write docs and best practices emphasize careful relabeling and recording to avoid unnecessary pressure. (prometheus.io)
3) Tune remote_write for throughput and reliability
- Prometheus offers options you can tune (batch size, max_shards, queue_config) to match your network and remote endpoint characteristics. Monitoring prometheus_remote_storage_samples_pending and CPU/network saturation are first-order signals that remote_write needs attention. (prometheus.io)
4) Use OpenTelemetry collector when you have mixed sources
- If you’re ingesting both Prometheus-format metrics and OpenTelemetry-format metrics, the OpenTelemetry Collector can forward via Prometheus remote_write to Mimir and will handle exponential histograms conversion when needed, removing the need to duplicate instrumentation. (grafana.com)
Practical snippets
Example: a minimal remote_write block for prometheus.yml
- This snippet shows the common fields, plus relabeling to drop unwanted labels (reduce cardinality).
remote_write:
- url: "https://mimir-prod.example/api/v1/push"
bearer_token: /etc/prometheus/secrets/mimir_token
queue_config:
max_samples_per_send: 1000
batch_send_deadline: 5s
# Basic relabeling to drop ephemeral labels and reduce cardinality
relabel_configs:
- source_labels: [__meta_kubernetes_pod_name]
regex: "(.*-pod-[0-9a-f]{8})"
action: replace
target_label: pod_basename
- source_labels: [instance]
regex: "(.*):.*"
action: replace
target_label: instance_name
- source_labels: [job]
regex: "dev-.*"
action: drop
Notes on the snippet
- Use relabeling aggressively to transform or drop high-cardinality fields before they reach the remote backend.
- The queue_config controls batching: tune max_samples_per_send and batch_send_deadline to balance throughput and memory.
Recording rules and local downsampling
- Move heavy aggregations into Prometheus recording rules so that you write compact precomputed series rather than many ad-hoc queries. For example, compute a 1-minute rate aggregate as a recording rule and ship that, instead of shipping every raw counter and computing expensive rates later.
Tuning and observability of the pipeline
- Monitor these Prometheus metrics at minimum: prometheus_remote_storage_samples_pending, prometheus_remote_storage_samples_total, and scrape latency. If samples_pending climbs, remote_write is struggling and either the endpoint or Prometheus tuning needs inspection. The Prometheus practices documentation explains common tuning levers and failure modes. (prometheus.io)
Grafana-side best practices
- Point Grafana’s data source to the long-term store for historical panels and to local Prometheus for ultra-low-latency panels. Use dashboards that can toggle time ranges and datasource sources when exploring anomalies.
- When querying long retained metrics, prefer range and aggregate queries (for example, using rate() over intervals) and rely on backend downsampling where available. Many backends, including Mimir, are designed to compact and downsample data for cost-efficient storage. (grafana.com)
Handling mixed metric ecosystems (Prometheus + OpenTelemetry)
- If you have OpenTelemetry-instrumented services, use the OpenTelemetry Collector as a bridge: it can scrape Prometheus endpoints and export via Prometheus remote_write to Grafana Mimir, while also accepting OTLP and converting histograms appropriately. This reduces duplication of instrumentation and centralizes export logic. (grafana.com)
Operational caveats and real-world gotchas
- WAL and recent-block availability: some long-term stores rely on write-ahead logs (WAL) or local ingesters for the most recent minutes/hours of data. If you depend on immediate consistency for short windows, verify how your chosen backend hybridizes WAL and object-storage blocks.
- Cost vs. fidelity trade-offs: decide which metrics need long-term retention at full cardinality (SLO/SLA KPIs) and which can be aggregated or sampled. Thoughtful metric hygiene can shrink storage needs by orders of magnitude.
- Multi-tenant and multi-cluster access: ensure you have tenant isolation (API keys, RBAC) and consistent label conventions across clusters to enable easy aggregation in Grafana.
What’s changed recently
- Long-term metric backends like Grafana Mimir have been actively optimized to separate read and write paths and improve durability and cost for large deployments. Those architectural changes are designed to make remote_write pipelines more resilient and performant at scale, helping teams keep both short-term alerting and long-term analytics workflows healthy. (grafana.com)
Final checklist (condensed)
- Keep local Prometheus for scraping, short-term rules, and alerts.
- Aggressively relabel and apply recording rules before remote_write.
- Monitor remote_write-specific metrics and tune queue_config and batch settings.
- Use the OpenTelemetry Collector if you’re mixing OTLP and Prometheus formats.
- Align labels and tenancy so Grafana dashboards can cleanly aggregate across clusters.
Conclusion A remote_write pipeline with Prometheus at the collection edge and a robust Prometheus-compatible long-term store like Grafana Mimir provides a pragmatic balance: fast local alerting where it matters, combined with scalable, cost-aware historical analytics for dashboards and SLO reporting. The recent evolution of long-term metric backends and closer OpenTelemetry interoperability make this pattern even more practical. Adopting it thoughtfully — by controlling cardinality, tuning remote_write, and separating concerns — will keep your dashboards useful, your retention affordable, and your incident response snappy. (grafana.com)