Most MikroTik deployments I audit have exactly one form of monitoring: someone opens WinBox when users complain. The router that carried traffic flawlessly for 400 days gets zero graphs, and then one day conntrack fills up, or a single CPU core pins at 100% while the average looks fine, and nobody can say when it started because nothing was recording.
Routers fail gradually before they fail completely. Interface errors creep up as an SFP dies. Connection counts climb toward max-entries during a slow UDP flood. CPU core 0 saturates while cores 1–3 idle. Every one of these is visible days in advance — if something is looking.
RouterOS 7 gives you three ways to get data out: SNMP (universal, boring, works), the API (what the good Prometheus exporters use), and the REST API (7.1+, easiest for ad-hoc scripting). This article sets up all three and — more importantly — tells you which metrics deserve alerts.
What Actually Matters
Before tooling, the signal list. These are the metrics that predict MikroTik outages in practice:
| Metric | Why | Where |
|---|---|---|
| CPU per core, not average | IRQ-bound work pins one core; average hides it | /system resource cpu print |
| Conntrack count vs max | Table full = new connections silently dropped | /ip firewall connection tracking print |
| Interface errors / drops | Dying SFPs, duplex mismatch, overruns | /interface ethernet print stats |
| Wireless signal / CCQ | Client experience degrades long before disassoc | registration table |
| Temperature, voltage, fans | Hardware death foretold | /system health print |
| Memory free | Slow leaks in long-running 7.x versions happen | /system resource print |
| Firmware/version drift | Fleet consistency | /system routerboard print |
The per-core point deserves emphasis. A CCR2004 showing “25% CPU” may actually be one core at 100% handling all PPPoE or IPsec interrupts. Check it directly:
/system resource cpu print# Columns: cpu, load, irq, disk — watch for one core loaded while others idle
# Find what's eating it/tool profile duration=10sConntrack is the other classic silent killer. When the table is full, the router drops new flows and existing sessions keep working — so it looks like “the internet is flaky” rather than “the router is down”:
/ip firewall connection tracking print# total-entries vs max-entries — alert at 70%SNMPv3: The Baseline
SNMP is still the lowest-friction path into Zabbix, LibreNMS, or PRTG. RouterOS ships with SNMP disabled and a default public community — enable the service, but never use that community. v1/v2c is cleartext; use SNMPv3 with authentication and encryption (security=private in MikroTik terms, authPriv in SNMP terms).
# Enable SNMP, set identity info/snmp set enabled=yes contact="noc@example.com" location="rack-12-hel1"
# Neutralize the default public community/snmp community set [find default=yes] name=not-public read-access=no addresses=127.0.0.1
# SNMPv3 user: SHA1 auth + AES privacy, restricted to the monitoring host/snmp community add name=monitor security=private \ authentication-protocol=SHA1 authentication-password=Str0ngAuthPass \ encryption-protocol=AES encryption-password=Str0ngPrivPass \ addresses=10.0.20.10/32 read-access=yes write-access=noBoth passwords must be at least 8 characters. The addresses= restriction matters: SNMP runs on UDP 161 and has no lockout mechanism, so scope it to your collector and firewall it on the input chain anyway (the management-plane article later in this series covers the firewall side).
Verify from the collector:
snmpwalk -v3 -l authPriv -u monitor \ -a SHA -A 'Str0ngAuthPass' -x AES -X 'Str0ngPrivPass' \ 10.0.20.1 1.3.6.1.2.1.1Traps exist too (/snmp set trap-target=10.0.20.10 trap-version=3 trap-community=monitor trap-generators=interfaces), but I treat SNMP traps as best-effort — polling plus syslog covers the same ground more reliably.
Prometheus: mktxp Is the Answer
If you run Prometheus and Grafana, skip SNMP exporters and generic scripts. The community has converged on mktxp — a Python exporter that talks the RouterOS API (TCP 8728), supports many routers concurrently, and ships with a genuinely good Grafana dashboard (ID 13679). The older Go mikrotik-exporter still works but sees far less maintenance; for new deployments use mktxp.
First, a dedicated read-only API user on each router:
/user group add name=monitoring policy=api,read/user add name=mktxp group=monitoring password=GeneratedLongPassword \ address=10.0.20.10/32The address= on the user means those credentials are useless from anywhere but the monitoring host — cheap defense in depth.
Then mktxp.conf on the collector:
[edge-router-1] hostname = 10.0.20.1 port = 8728 username = mktxp password = GeneratedLongPassword use_ssl = False
health = True interface = True firewall = True connections = True # conntrack count — the alert you actually want route = True wireless = True capsman = True dhcp = TrueAnd the Prometheus scrape job:
# prometheus.ymlscrape_configs: - job_name: 'mikrotik' static_configs: - targets: ['mktxp-host:49090']Alert rules worth having from day one: conntrack above 70% of max, any interface error counter increasing, per-core CPU above 85% for 5 minutes, temperature above the platform’s spec, and mktxp scrape failures themselves (a router that stops answering its API is a signal, not a gap).
REST API: Polling Without an Exporter
RouterOS 7.1+ exposes a REST API over the www-ssl service — every console command mapped to a URL under /rest/. It uses HTTP basic auth against normal router users. Do not enable plain www for this; put a certificate on www-ssl and restrict the service address.
/ip service set www-ssl disabled=no certificate=mgmt-cert address=10.0.20.0/24Then anything you can print, you can GET:
# Full resource statecurl -sk -u mktxp:GeneratedLongPassword \ https://10.0.20.1/rest/system/resource
# Just the fields you care aboutcurl -sk -u mktxp:GeneratedLongPassword \ "https://10.0.20.1/rest/interface?.proplist=name,rx-error,tx-error,running"
# Health sensorscurl -sk -u mktxp:GeneratedLongPassword \ https://10.0.20.1/rest/system/healthAll values come back as JSON strings, and commands time out at 60 seconds. REST is perfect for a cron job that checks 50 routers for version drift, or for wiring a quick check into a CI pipeline before and after config pushes. It is not a streaming interface — there is no long-poll or subscribe; you poll.
Hardware Health
On physical RouterBOARD and CCR hardware, /system health exposes temperature, voltage, fan speeds, and on some models PSU state and power consumption:
/system health print# Columns: name, value, type# e.g. temperature 41 C, voltage 24.2 V, fan1 4980 RPMWhat to watch:
- Voltage on PoE- or DC-fed devices. A slowly sagging supply (24.2 → 22.1 V over weeks) is a failing PSU or corroding connector. Sudden reboots with no log entries are almost always power.
- Temperature. Note that via SNMP and the API some platforms report temperature multiplied by 10 (
415= 41.5 °C) while the CLI shows the real value — normalize in your collector, or your “critical: 415 degrees” alert will cause a fun morning. - Fans on CCRs. A dead fan gives you weeks of margin in January and none in July.
CHR instances and x86 installs have no health subsystem — monitor the hypervisor instead.
Wireless: CCQ and Its Successors
On the legacy /interface wireless driver, CCQ (Client Connection Quality) is the one number that summarizes client experience — it factors retransmissions and rate degradation. Watch it per client:
/interface wireless registration-table print stats# tx-ccq / rx-ccq below ~70% = investigate interference or coverageThe newer /interface/wifi driver (wifi-qcom packages on ax hardware) does not expose CCQ. There you monitor signal per registration plus tx/rx PHY rates:
/interface/wifi registration-table print# signal worse than -75 dBm or rates stuck at minimums = same conversationmktxp’s wireless and capsman collectors pick both variants up, so the Grafana dashboard shows per-client signal history — which turns “WiFi was weird yesterday” tickets into answerable questions.
Verification: Prove the Pipeline Works
Monitoring that has never fired is untested code. After setup:
# Generate interface counter movement and watch it appear in Grafana/tool bandwidth-test address=10.0.20.10 direction=both duration=30s
# Confirm SNMP answers only from the collector (this should time out elsewhere)# From a non-collector host: snmpwalk -v3 ... 10.0.20.1 -> timeout
# Watch what the exporter's user is doing/user active print/log print where message~"logged in"Then pull the power on a test AP and time how long until you get paged. If the answer is “we didn’t,” fix that before trusting anything else.
Closing Thoughts
Minimum viable RouterOS monitoring: mktxp + Prometheus + the 13679 dashboard, SNMPv3 only if a legacy NMS requires it, and alerts on per-core CPU, conntrack percentage, interface errors, and temperature. That covers perhaps 90% of the failures these boxes actually have.
Two habits complete the picture. First, monitor the monitoring — scrape failures are first-class alerts. Second, keep retention long enough to answer “when did this start?” — 30 days minimum, because the interesting degradations are slow.
Metrics tell you that something happened. The next article covers logging and NetFlow — which tell you what happened. I covered the equivalent stack for VyOS in the VyOS Guide’s observability article; the philosophy is identical, only the tooling changes.