Skip to content

Why This Exporter

Last reviewed: 2026-07.

The Meraki ecosystem has several community Prometheus exporters, most of them small single-file scripts that poll a handful of getOrganization*/getNetwork* endpoints on a fixed interval and print gauges. Those are good choices for a small estate or a quick proof of concept. This page states, factually and without disparaging any specific alternative, what this exporter does differently and why, so you can decide whether the extra surface area is worth it for your deployment.

For the full metric-by-device-model breakdown see the Support Matrix, and for quick operational answers see the FAQ. This page is about architecture and positioning, not a feature checklist.

Design choices specific to this exporter

Async collection with bounded concurrency. The Meraki Python SDK is synchronous, so collectors run it via asyncio.to_thread() and fan out per-device/per-network work through ManagedTaskGroup, which caps in-flight requests at settings.api.concurrency_limit rather than firing an unbounded asyncio.gather(). This keeps a single collection cycle from saturating the Meraki API's per-organization rate limit even against large estates.

An adaptive, budget-aware endpoint scheduler, not one fixed interval. Every API fetch is declared as an endpoint group with its own volatility floor (core/scheduler.py) — sensor readings floor around 60s, device/org/network-health groups around 300s, configuration and security settings much higher — and each collector runs its own group-clocked loop off those floors, so a dashboard's sensor panel refreshes every minute without re-fetching device inventory every minute too. On top of the floors, the scheduler (scheduler.mode=adaptive, the default, not an opt-in) automatically stretches individual groups' intervals when their combined request demand would exceed the configured API budget (requests_per_second × shared_fraction, adjusted live by AIMD feedback from the rate limiter), rather than either over-running the rate limit or dropping data outright. A fixed mode (floors/pins only, no stretching, no AIMD) exists as a debugging/transition fallback, not the recommended default. See Scheduler Architecture for the full mechanism.

Network filtering enforced at a single choke point. Every collector that needs a list of networks goes through OrganizationInventory.get_networks(org_id), which is the sole place the configured include/exclude NetworkFilter (by name glob, ID, or tag) is applied. This is a structural rule in this codebase, not just a convention — collectors are not permitted to call getOrganizationNetworks directly. For an operator, the practical effect is that scoping the exporter to a subset of networks (by tag, or by explicit include/exclude lists) is guaranteed to apply consistently everywhere metrics are produced, rather than needing to be re-implemented per collector.

Metric lifecycle / expiration. Devices and networks that disappear from the Meraki inventory (decommissioned, removed, renamed) have their previously-emitted series expired rather than left as permanent stale time series in Prometheus. This matters for exporters that run for months against a changing estate — without expiration, /metrics output only grows.

A published metric stability policy. The Metric Stability & Deprecation Policy states, as of the 1.0 release, exactly which metric names, labels, and units are covered by a compatibility promise across 1.x, which are marked experimental and may still change, and how a post-1.0 rename would be handled (old name kept alongside new for a deprecation window, not a silent breaking change). Building dashboards and alerts against a documented stability contract is different from building against "whatever fields happen to exist in the current script."

OpenTelemetry as a self-observability and product-data layer, not a metrics duplicate. The exporter can emit its own OTel traces (collection cycles, API calls) for debugging itself, and can optionally emit a structured OTel data-log channel for high-cardinality per-entity data (e.g. per-client information) that would be inappropriate as a labelled Prometheus series — see Data logs vs. metrics for the exact boundary rule. There is also an optional, opt-in OTLP metrics bridge that periodically pushes the existing Prometheus registry to an OTLP metrics endpoint for operators whose collection pipeline is push-based rather than scrape-based; enabling it does not change /metrics output. Prometheus /metrics remains the sole metrics surface — none of this is a second, parallel metrics system.

Container image and Helm chart, deliberately no PyPI package. For v1 this exporter ships only as a container image plus an official Helm chart for Kubernetes — there is no pip install. That is a deliberate scope decision (see Deployment & Operations), not an oversight: it keeps the supported surface to one artifact type with one dependency set, at the cost of not supporting a bare-metal/venv install path.

When to pick this exporter vs a simpler community script

Pick a small single-file community exporter when you have a handful of networks, want to read and modify the entire collection logic yourself in an afternoon, and don't need scoping, expiration, or a stability contract — the operational simplicity of "one script, one process" is a real advantage at that scale.

Pick this exporter when any of the following apply: you run enough networks/devices that uncoordinated per-device polling risks the Meraki API rate limit; you need to scope collection to a subset of networks (by tag or name) without hand-rolling that filter yourself; you want metrics that survive months of inventory churn without accumulating stale series; you want a documented compatibility guarantee before wiring dashboards/alerts to specific metric names; or you're deploying into Kubernetes and want a maintained Helm chart rather than hand-writing a Deployment manifest.

See the Support Matrix for which device models and metric families are actually covered today, and the FAQ for setup and troubleshooting specifics.