Skip to main content

Mimir - Scalable Prometheus metrics storage

Prometheus is a great metrics server, but it was designed as a single instance. Once you want long retention, high availability and multi-tenancy, you hit a wall fast. Mimir solves that problem while keeping the same data format and query language, with a scalable backend. On France Nuage, Mimir is managed: nothing to deploy, your metrics land in it automatically, and Grafana is already wired to it.

Why Mimir?

Mimir is a community fork of Cortex, maintained by Grafana Labs. It does everything Prometheus does, but at a different scale.

  • Long term: retention far beyond what a single Prometheus instance can hold, without performance loss
  • Multi-tenant: strict tenant isolation via the X-Scope-OrgID header, perfect for separating environments or teams
  • High availability: automatic deduplication of samples written by multiple Prometheus/Alloy instances
  • PromQL: exactly the same query language as Prometheus — your dashboards and alerts keep working unchanged
  • Prometheus-compatible: Mimir speaks Prometheus remote_write, so any Prometheus scraper (Alloy, Agent, Prometheus itself) can write to it

Comparison

CriterionMimir (France Nuage)Prometheus aloneThanosVictoriaMetricsDatadog
Query languagePromQLPromQLPromQLMetricsQL (≈PromQL)Proprietary
Multi-tenantYes, nativeNoYes, sidecarYes, via clusterYes, paid
Long retentionYes (S3)Disk-limitedYes (S3)YesYes
High availabilityYes, dedupNoYes, replicasYesYes
Open sourceYes (AGPLv3)Yes (Apache 2.0)Yes (Apache 2.0)Yes (Apache 2.0)No
Sovereign hostingYes (France)Up to youUp to youUp to youNo (USA)
CostIncluded in the stackFree + opsFree + opsFree + opsPer host/metric
Ops costZeroYoursYoursYoursZero

In practice

If you run a single small service, Prometheus alone is fine. As soon as you have multiple environments, multiple teams, or you want a year of history, Mimir removes a ton of complexity. Thanos and VictoriaMetrics address the same need, but you have to operate them. On France Nuage, that work is already done.

As for Datadog, the bill climbs with hosts and custom metrics. With Mimir, you push what you want within your tenant's cardinality limits — no end-of-month surprises.

Multi-tenant by namespace

On France Nuage, one Mimir tenant equals one Kubernetes namespace. When Alloy scrapes a pod in the my-app namespace, it writes to Mimir with X-Scope-OrgID: my-app. Result:

  • Your metrics are isolated from other teams by default, with zero configuration
  • Your France Nuage Grafana instance is pre-wired to your tenant, you don't have to handle the header on the read path
  • If you have multiple environments (staging, production), create two namespaces and you get two separate tenants for free

Portability

  • PromQL: the industry standard. Your queries and dashboards are portable to any Prometheus-compatible backend
  • Standard remote_write protocol: if you ever want to write to another backend, just change the URL
  • Native Prometheus metrics format: no lock-in on the data format
  • AGPLv3 license: the code stays open, Mimir can't go proprietary

Mimir vs self-hosting

You could deploy Mimir yourself. Here's what it takes in practice:

AspectSelf-hostedFrance Nuage
Object storageTo provision (S3, MinIO)Included
Distributor/Ingester/QuerierTo deployDeployed
Horizontal scalingYour jobManaged
HA dedupTo configureOn
Long-term retentionTo tune1 year included
Cardinality limitsTo definePre-set
BackupsTo configureAutomatic
Mimir supervisionYour jobIncluded
Security updatesTo watchApplied

Quick start

1. Nothing to deploy

Mimir is already running on every France Nuage Kubernetes cluster. No Helm chart to install, no CRD to create.

2. Add annotations on your pods

Alloy watches the cluster continuously and scrapes every pod that carries these annotations:

metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
prometheus.io/path: "/metrics"

For a step-by-step tutorial with a Node.js example, read Expose Prometheus metrics from your Kubernetes pods to Mimir.

3. Query from Grafana

Open your France Nuage Grafana instance. The Mimir datasource is already configured and wired to your tenant. Go to Explore, pick Mimir, and type a PromQL query:

sum(rate(http_requests_total[5m])) by (status)

Going further

Writing PromQL queries

Mimir speaks PromQL exactly like Prometheus. Every Prometheus community example works as-is. A few useful queries to get started:

# 5xx error rate over 5 minutes
sum(rate(http_requests_total{status=~"5.."}[5m]))

# P95 latency per endpoint
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, endpoint)
)

# Pods that restarted in the last hour
increase(kube_pod_container_status_restarts_total[1h]) > 0

Alerting

Mimir ships with a ruler component that evaluates your alert rules continuously and pushes them to Alertmanager. On France Nuage, Alertmanager is pre-configured — you just create your rules through the Grafana UI (Alerting > Alert rules) or version them in Git and apply them.

Ready-to-use Kubernetes metrics

Alloy automatically collects metrics from kube-state-metrics, node-exporter and cAdvisor on every cluster. You can query right away:

# CPU usage per pod
sum(rate(container_cpu_usage_seconds_total{namespace="my-app"}[5m])) by (pod)

# Memory usage per pod
container_memory_working_set_bytes{namespace="my-app"} / 1024 / 1024

Best practices

  • Control label cardinality: avoid infinite-valued labels (user_id, request_id, trace_id). Every unique combination creates a new time series and eats memory
  • Follow Prometheus naming conventions: _total for counters, _seconds for durations, _bytes for sizes
  • Consistent labels: an app and env label across all your metrics to keep queries simple
  • One namespace per environment: staging and production in separate namespaces give you two isolated Mimir tenants
  • Versioned dashboards: export your Grafana dashboards as JSON and commit them to Git

References