Prometheus Network Monitoring
Official site · Latest version: 3.13.0
Prometheus for Network Monitoring
Prometheus is a pull-based metrics platform that has become the default observability choice for cloud-native infrastructure. Network engineers sometimes dismiss it as “a Kubernetes thing”, which is understandable — most tutorials are container-centric. But the scrape model maps surprisingly well onto SNMP polling, and the combination of Prometheus + snmp_exporter + Grafana gives you a fully open-source network observability stack with no per-device licensing.
This page covers what that stack actually looks like, where it performs well, and where you should look elsewhere.
How Prometheus collects metrics
Prometheus scrapes targets over HTTP at a configured interval. Each target exposes a /metrics endpoint returning labelled time-series data in Prometheus exposition format. The server stores those samples in its local TSDB (time-series database) and makes them queryable via PromQL.
That pull model has a practical consequence for network monitoring: your routers and switches cannot expose a /metrics endpoint. You need an exporter — a process that speaks SNMP toward the device and speaks Prometheus exposition format toward the Prometheus server.
Prometheus server
│
│ GET /snmp?target=192.0.2.1&module=if_mib
▼
snmp_exporter ←──── SNMP GET/GETBULK ────► router / switch
The exporter is stateless. Prometheus passes the device address as a query parameter on each scrape, so a single snmp_exporter instance can fan out across hundreds of devices without maintaining persistent state per device.
Scrape interval vs SNMP polling interval: these are the same thing. Set scrape_interval in the Prometheus job and that determines how often SNMP counters are read. Fifteen seconds is common for interface counters; 60–300 seconds for environmental or BGP state. Going below 10 seconds rarely gains you anything and increases load on control-plane CPUs.
snmp_exporter in practice
snmp_exporter (current release: 0.30.1, as of July 2026) translates SNMP OIDs into Prometheus metrics. It is driven by a snmp.yml config file that maps MIBs to metric names and label sets.
Generating snmp.yml
Writing snmp.yml by hand is not the intended workflow. The project ships a generator that reads MIB files and outputs the config automatically:
# clone the generator, not the exporter
git clone https://github.com/prometheus/snmp_exporter
cd snmp_exporter/generator
# install MIBs (example: net-snmp defaults + vendor MIBs)
apt-get install snmp-mibs-downloader # or brew install net-snmp on macOS
cp /path/to/vendor/CISCO-IF-EXTENSION-MIB.my mibs/
# edit generator.yml to select modules + OIDs, then:
go run . generate
The output snmp.yml lands in the current directory. Commit it alongside your exporter deployment. The generator is documented at snmp_exporter/generator/README.md.
A minimal Prometheus scrape job
# prometheus.yml
scrape_configs:
- job_name: "snmp_network"
static_configs:
- targets:
- 192.0.2.1 # core-sw-01
- 192.0.2.2 # core-sw-02
metrics_path: /snmp
params:
module: [if_mib]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: snmp-exporter:9116 # the exporter's address
The relabel_configs block is boilerplate for every SNMP job: it rewrites __address__ so Prometheus hits the exporter, not the device, while preserving the device IP as the instance label.
For dynamic environments, replace static_configs with a file-based SD block pointing to a JSON/YAML inventory, or use a service-discovery integration (Consul, EC2, etc.).
What IF-MIB gives you out of the box
The bundled if_mib module covers ifTable and ifXTable:
| Metric | OID | Notes |
|---|---|---|
ifHCInOctets | 1.3.6.1.2.1.31.1.1.1.6 | 64-bit in-bytes counter |
ifHCOutOctets | 1.3.6.1.2.1.31.1.1.1.10 | 64-bit out-bytes counter |
ifOperStatus | 1.3.6.1.2.1.2.2.1.8 | 1=up, 2=down, 7=lowerLayerDown |
ifInErrors / ifOutErrors | .14 / .20 | Error counters |
ifInDiscards / ifOutDiscards | .13 / .19 | Drop counters |
Vendor-specific MIBs (CISCO-PROCESS-MIB, JUNIPER-MIB, etc.) require adding modules in generator.yml.
Querying with PromQL
PromQL is a functional query language. The learning curve is real, but for network metrics you need roughly four patterns.
Interface utilisation (%)
# ingress utilisation on a 1 Gbps interface
100 * (
rate(ifHCInOctets{instance="192.0.2.1", ifDescr="GigabitEthernet0/1"}[5m]) * 8
)
/ 1e9
rate() computes per-second delta from a counter, averaged over the window. Multiply by 8 to convert bytes → bits. Divide by link speed in bps. The [5m] window should be at least 2–3× your scrape interval.
Warning:
rate()assumes monotonically increasing counters and handles wraps correctly for 64-bit counters. For 32-bitifInOctets/ifOutOctets, wraps occur at ~4 GB — not uncommon on a 1 Gbps port within an hour. Always preferifHCInOctets/ifHCOutOctetswhere the device supports them.
Interface error rate
rate(ifInErrors{instance="192.0.2.1"}[5m])
/ rate(ifHCInOctets{instance="192.0.2.1"}[5m])
Top-N interfaces by throughput
topk(10,
rate(ifHCInOctets[5m]) * 8
)
Alerting: interface down
# alerts/network.yml
groups:
- name: network_interfaces
rules:
- alert: InterfaceDown
expr: ifOperStatus{ifDescr!~"Loopback.*"} == 2
for: 2m
labels:
severity: warning
annotations:
summary: "Interface {{ $labels.ifDescr }} down on {{ $labels.instance }}"
The for: 2m guard prevents flap noise. Remove it only if your scrape interval is already 60 s+.
Grafana integration
Prometheus is Grafana’s native data source. Add it under Connections → Data sources → Prometheus, set the URL to your Prometheus server, and you’re querying immediately.
For network dashboards, the community SNMP / Network Stats dashboard (ID 11169) is a reasonable starting point — import it, adjust the job and instance variables to match your label scheme, then modify from there. Treat it as a template, not a finished product; the variable queries often need tuning for non-default label names.
Grafana’s Transformations panel is worth knowing for network work: Group By lets you aggregate across all interfaces per device without writing extra PromQL.
When this stack fits
Good fit:
- Mixed-vendor environments where no single NMS covers everything.
- Teams already running Prometheus for server/container metrics — one tool, consistent alerting pipeline.
- Environments where SNMP v2c/v3 polling is already in place;
snmp_exporterslots in alongside existing tools. - Budget-constrained teams: the full stack (Prometheus + snmp_exporter + Grafana) has zero licensing cost.
Poor fit:
- Large-scale flow analysis (NetFlow, sFlow, IPFIX): Prometheus is not a flow collector. Look at Grafana Alloy + Loki or dedicated tools (ntopng, ElastiFlow).
- Sub-10-second granularity at scale: the scrape model and TSDB write path start showing latency above ~1 million active series or very high cardinality (per-flow labels, for instance).
- Organisations needing a point-and-click NMS with built-in topology discovery, automated baselining, or SLA reporting. The Prometheus stack is composable but not opinionated; you build the workflows yourself.
- Teams without SNMP access to devices: if your network vendor locks you to a proprietary streaming telemetry protocol with no Prometheus receiver, you need a different collector (Telegraf with the relevant input plugin is a common workaround, feeding into Prometheus via remote-write).
Retention and scaling considerations
Default Prometheus local retention is 15 days. Set --storage.tsdb.retention.time to suit your needs; 90 days is workable on modest hardware for a pure-network SNMP dataset (counter-only series compress well).
For longer retention or multi-site federation, remote-write to a long-term storage backend:
- Thanos — object-store backed, operator-friendly.
- Mimir — Grafana Labs’ horizontally scalable TSDB; fully open-source.
- VictoriaMetrics — popular for its compression ratio and simple single-binary mode.
All three accept Prometheus remote-write and are queryable from Grafana without changing your dashboard PromQL.
Quick-start checklist
- Deploy
snmp_exporter0.30.1 (release notes) — single binary or Docker image. - Run the generator against your MIBs; commit the resulting
snmp.yml. - Add a
snmp_networkscrape job toprometheus.ymlusing the relabel pattern above. - Verify in Prometheus UI:
up{job="snmp_network"}should show1per device. - Import Grafana dashboard 11169; adjust variables.
- Write alert rules for
ifOperStatus == 2and high error rates. - Configure remote-write if retention > 15 days.
FAQ
Does snmp_exporter support SNMPv3?
Yes. Configure auth and priv fields in the module’s walk section of snmp.yml. The generator supports v3 auth via generator.yml — see the generator auth docs.
How do I monitor BGP session state with Prometheus?
Add the BGP4-MIB (RFC 4271) to your generator config. bgpPeerState (OID 1.3.6.1.2.1.15.3.1.2) returns an integer; alert when it drops below 6 (established). Vendor-specific BGP MIBs give you prefix counts and AS paths.
Can Prometheus replace my existing SNMP trap receiver? No. Prometheus is poll-based; it does not receive unsolicited trap messages. Run a separate trap receiver (snmptrapd, Elastalert, or your NMS) alongside it.
What scrape interval should I use? For interface counters, 15–30 seconds is the common choice. For CPU/memory/environment, 60 seconds is usually sufficient. Check your device’s SNMP agent documentation — some lower-end switches struggle to respond to SNMP polls faster than once per 30 seconds under load.
Is Prometheus suitable for monitoring hundreds of devices? Yes, with caveats. A single Prometheus server handles thousands of devices comfortably if you control cardinality. The risk is label explosion: avoid high-cardinality labels like per-MAC-address or per-BGP-prefix. At 500+ devices, consider sharding by site/region into multiple Prometheus servers behind Thanos or Mimir.
Sources & further reading
- Prometheus Documentation — Configuration (Prometheus 3.13.0, as of July 2026)
- snmp_exporter GitHub — README & generator docs (v0.30.1)
- Prometheus TSDB storage internals
- PromQL functions reference
- Grafana → Add Prometheus data source
- Thanos quickstart
- Grafana Mimir documentation
- RFC 2863 — The Interfaces Group MIB (IF-MIB)
Internal links: see also SolarWinds SWQL to DDSQL conversion — interface utilisation for a worked PromQL comparison example; Grafana overview for dashboard configuration depth.