mikrotik-exporter turns a RouterOS API session into Prometheus metrics
prometheus mikrotik device(s) exporter
At a glance
- What is it?
- mikrotik-exporter is a Go Prometheus exporter that reads MikroTik router configuration over the RouterOS API and publishes interface counters and system resources, for one device or for many configured in a YAML file. It suits operators who want router telemetry in the same scrape pipeline as the rest of their infrastructure, and its caveats are that the newest tagged release is from 2019, that the metric set is narrow, and that several device features are opt-in switches.
- Who is it for?
- Operators who run MikroTik routers alongside a Prometheus stack and want interface and system telemetry scraped the same way as everything else are the people mikrotik-exporter is for, and the read-only API user with the api, read and winbox policies is a small, well-defined footprint on the router.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 112 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The exporter needs a read-only RouterOS user, and that is the whole setup
The access model is the first thing to get right, and it is refreshingly small. You create a group on the device that has API and read-only access, and the README gives the exact command, `/user group add name=prometheus policy=api,read,winbox`. If the lte package is enabled it requires also the test policy, so the group becomes `/user group add name=prometheus policy=api,read,winbox,test`. Then you create the user that the exporter will authenticate as with `/user add name=prometheus group=prometheus password=changeme`. Three policies and one user is the entire privilege footprint, and the winbox policy is there so the group can be managed over the same channel the operator already uses. The documentation also says a user will be required that has read-only access to the device configuration via the API, which is the same requirement stated as a rule rather than a recipe. The winbox and test policy details only matter for the LTE case, so on a wired router the shorter group definition is enough. This is a much smaller ask than most exporters make of network devices, and it is the reason the exporter can be pointed at a router without asking the router owner for anything more than a credential.
One device on the command line, several devices in a YAML file
The configuration splits cleanly by scale. For a single device everything is on the command line, with the address of the router, the label name for the device in the metrics output, and the user and password the exporter will use to access the API, so the invocation is `./mikrotik-exporter -address 10.10.0.1 -device my_router -password changeme -user prometheus`. The user and password can also come from the MIKROTIK_USER and MIKROTIK_PASSWORD environment variables, which is the form to prefer once a credential is involved, because a flag value ends up in the process list and a shell history while an environment variable is at least inherited rather than typed.
MIKROTIK_USER=prometheus
MIKROTIK_PASSWORD=changeme
./mikrotik-exporter -address 10.10.0.1 -device my_routerbash
Multiple devices require a configuration file, given with the -config-file flag and in YAML format, so the invocation is `./mikrotik-exporter -config-file config.yml`. The example configuration shows the shape, where each entry has a name, an address, a user and a password, and an optional port.
devices:
- name: my_router
address: 10.10.0.1
user: prometheus
password: changeme
- name: my_second_router
address: 10.10.0.2
port: 8999
user: prometheus2
password: password_to_second_router
wifiwave2: trueSRV records let the exporter discover routers instead of listing them
The configuration supports a discovery mechanism that is worth understanding because it changes how the exporter scales. If you add a device with the srv parameter instead of address, the exporter performs a DNS query to obtain the SRV record and discovers the devices dynamically. The example shows both a plain record, _mikrotik._udp.example.com, and one with a custom DNS section that names the address and port of the resolver to use.
- name: routers_srv_dns
srv:
record: _mikrotik._udp.example.com
user: prometheus
password: password_to_all_dns_routers
- name: routers_srv_custom_dns
srv:
record: _mikrotik2._udp.example.com
dns:
address: 1.1.1.1
port: 53
user: prometheus
password: password_to_all_dns_routersbash
So a fleet of routers can be added to DNS and picked up without editing the exporter configuration, with a shared password for the group. The limitation is that the same credentials apply to every device found under that record, since the credential is attached to the configuration entry rather than to each discovered host. That is a reasonable trade for a homogeneous fleet and a problem for a mixed one.
Ten feature switches decide what gets collected at all
The features block in the configuration file is the part that surprises new users, because the exporter does not collect everything it can by default. The example lists bgp, dhcp, dhcpv6, dhcpl, routes, pools, optics, wlanif and wlansta, each with a true value.
features:
bgp: true
dhcp: true
dhcpv6: true
dhcpl: true
routes: true
pools: true
optics: true
wlanif: true
wlansta: truebash
So the metric set is not a fixed set of everything the API exposes, it is a set of opt-in collectors. The reasoning is presumably that each of these walks a part of the RouterOS configuration tree, and on a busy router that is work you may not want repeated on every scrape. The documentation states the current scope plainly, that the exporter collects metrics for interfaces and system resources, and that others can be added as long as published via the API. That is a small but honest scope statement, and it tells you that a metric you do not see in the output is not a bug until you have checked the features block.
Metric labels carry the address, the interface and the device name
The output format is ordinary Prometheus exposition, and the labels are what make multi-device scraping usable. The interface byte counter appears with the address, the interface name and the device name.
mikrotik_interface_tx_byte{address="10.10.0.1",interface="ether2",name="my_router"} 1.4189902583e+10
mikrotik_interface_tx_byte{address="10.10.0.1",interface="ether3",name="my_router"} 2.263768666e+09bash
The device name is the label you supplied with the -device flag or the name field in the config file, and it is what lets one Prometheus instance hold metrics from several routers without a collision. The address label is a convenience for a human reading a graph, and it also means the same router reached over two addresses produces two label sets, which is worth remembering when a router has several interfaces. The metric naming is prefixed with mikrotik_ throughout, which is what keeps it separate from the exporter's own process metrics in a standard Prometheus installation.
The wifiwave2 package changes the API and the attributes you get
One device-specific caveat is documented in detail, and it will bite anyone with a recent MikroTik wireless install. The wifiwave2 option is for devices that have the wifiwave2 package, which replaces the wireless implementation that is installed, and it is necessary because wifiwave2 has a slightly different API and exposes a slightly smaller set of attributes, for example no signal-to-noise. The example configuration applies it to a single device with wifiwave2 set to true, and the feature list separately includes wlanif and wlansta for wireless interface and station metrics. The practical guidance is to treat the two wireless implementations as different backends rather than as the same collector with different data, and to check which one a device actually runs before interpreting a missing wireless metric. This is the sort of detail that a config example communicates in one line and a troubleshooting session would take an hour to rediscover.
The container build runs the test suite before it produces a binary
The Dockerfile is a two-stage build that says something about how the project is put together. The builder stage starts from golang:1.25.1-bookworm, copies go.mod and go.sum first and runs go mod download, then copies the rest of the source and runs go test ./... before building. The final stage is debian:12.12-slim with the binary copied in, the start.sh script from the scripts directory, and the entrypoint set to that script. The port exposed is 9436, which is the conventional Prometheus exporter port. Running the tests during the image build is a deliberate choice, since it means a broken build fails at image build time rather than at deploy time, and it is also why a change that passes locally but fails in the container is caught early. The go.mod pins Go 1.25.0 and a small set of direct dependencies, the Prometheus client libraries, logrus for logging, the miekg DNS library for the SRV lookups, a YAML parser and the routeros.v2 client for the API.
Where mikrotik-exporter is the wrong choice
The first wrong case is a team that wants router metrics without running an exporter at all, because MikroTik devices have their own graphing and SNMP story, and an exporter scraping the API on a schedule is a second path to the same data. The second wrong case is a large fleet with heterogeneous credentials, because the SRV discovery model attaches one credential per configuration entry, so a mixed fleet either needs one entry per credential set or a shared account. The third is a deployment that needs metrics the exporter does not publish. The documentation is clear that the current scope is interfaces and system resources, and that more can be added as long as they are published via the API, which means new collectors are development work rather than configuration. The fourth is a team that requires a supported release line, since the newest tagged release is 1.0.12-DEVEL from 2019-11-16, a development version rather than a numbered release, and the trunk branch is where the current work lands. The fifth is anyone expecting the collector set to be a stable contract, because the feature switches mean the metric set is a property of your configuration file rather than of the binary.
Editorial conclusion
Operators who run MikroTik routers alongside a Prometheus stack and want interface and system telemetry scraped the same way as everything else are the people mikrotik-exporter is for, and the read-only API user with the api, read and winbox policies is a small, well-defined footprint on the router. It is the wrong tool for anyone who needs router metrics beyond interfaces and system resources, since the documentation says others can be added as long as they are published via the API, and it is a poor foundation for a long-lived deployment without a maintainer, since the newest tagged release is 1.0.12-DEVEL from 2019 and the last push was on 2026-07-03. Check three things before you build on it: that the features you care about are switched on in the config file, since bgp, dhcp, dhcpv6, dhcpl, routes, pools, optics, wlanif and wlansta are all opt-in, that your device's API is reachable from the exporter, and that your wifiwave2 devices are configured correctly, since that package has a different API and exposes a smaller set of attributes. The licence is BSD-3-Clause.
Frequently asked questions
What permissions does the MikroTik user need for the exporter?
Create a group with the api, read and winbox policies using /user group add name=prometheus policy=api,read,winbox, and add the test policy as well if the lte package is enabled. Then create the user in that group with /user add.
How do I run mikrotik-exporter against a single router?
Pass the address, the device label, and the credentials on the command line, for example ./mikrotik-exporter -address 10.10.0.1 -device my_router -password changeme -user prometheus. The user and password can also be supplied through the MIKROTIK_USER and MIKROTIK_PASSWORD environment variables.
How does mikrotik-exporter monitor several routers at once?
Multiple devices require a YAML configuration file given with the -config-file flag. Each device entry has a name, an address, a user and a password, and an entry using srv instead of address makes the exporter discover devices through a DNS SRV record.
Why am I not seeing metrics for BGP, DHCP or wireless in mikrotik-exporter?
Those collectors are opt-in through the features block of the configuration file, where bgp, dhcp, dhcpv6, dhcpl, routes, pools, optics, wlanif and wlansta can each be enabled. The exporter collects metrics for interfaces and system resources by default.
What is the wifiwave2 option for in mikrotik-exporter?
It is for devices running the wifiwave2 package, which replaces the installed wireless implementation. The option is necessary because wifiwave2 has a slightly different API and exposes a slightly smaller set of attributes, for example no signal-to-noise.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nshttpd-mikrotik-exporter)Was this useful?