Skip to content

mikroscope

The RouterOS API reports CPU load once a second. mikroscope runs on the router, in a container, and reads the kernel's own counters at 1 to 100 Hz — for whoever has to say what a MikroTik device did inside that second. Two MIT-licensed binaries, and what the observer costs the router measured rather than promised, first thing below.

Measured, not budgeted

The first three are from the agent's own cgroup, carried on every sample; the fourth is from InfluxDB 3, the one sink the collector forwarded to. Each of the first three is one 300 s window at steady state, not repeated, so none has a spread. At 10 Hz the memory is inside the ≤ 16 MiB the budget asks for and the CPU is above the ≤ 2 %. The router, the RouterOS version and the date are on Tested on.

A one-second average is a report about a second

The RouterOS API reports cpu-load once a second. A core saturated for 100 ms and idle for the other 900 moves a four-core, one-second average by 2.5 %. That is arithmetic, not a measurement, and the figure is true: it just cannot say when.

The agent reads /proc/stat, /proc/interrupts, /proc/softirqs and /proc/net/softnet_stat from inside the router, at 10 Hz by default, and ships raw tick deltas with the interval each one covers. It never computes a percentage; the window is yours.

The floor is the kernel's, not the tool's. /proc/stat counts in ticks of 10 ms, so a 100 ms sample resolves one core to 10 % steps. There is nothing finer to read where the kernel has no PSI and no schedstat, and the tested router has neither (Tested on).

How many seconds cpu-load averages over →

What it costs, at three rates

Conditions: 300 s windows at steady state (ring full), full source set, the shipped configuration — a 60 s ring, the memory limit derived from it and the default 64M container cap — with the collector forwarding to InfluxDB 3. Each row is one window, not repeated, so no row has a spread; memory differs by row because the ring and the memory limit do.

The measured runs
ratefloorsCPU of one coreµs/sampleRSSslipped ticksgaps / drops
10 Hz (default)default2.69 %2 68513.2 MiB00 / 0
50 Hzdefault9.63 %1 92623.3 MiB00 / 0
100 Hzdefault16.83 %1 68445.7 MiB5 (0.02 %)0 / 0

Nothing was lost at any of these rates: every sink reported 0 gaps and 0 drops, and the delivered rate matched the configured one to three figures. At the default floors and 100 Hz, a whole tick's sources were read in under 2 ms for 97.7 % of samples, inside a 10 ms period.

All six runs, including every source on every tick →

The router's CPU from the kernel, its interfaces from the API

Kernel tier · the agent · 10 to 100 Hz

Global inside the container, so these are the router's own: per-core CPU ticks, interrupts, softirqs, softnet drops and time squeezes, /proc/meminfo, /proc/vmstat, load and disk I/O. A privileged container adds the kernel log as timestamped events and the global slab caches.

API tier · the collector · 1 Hz

The container has its own network namespace, so /proc/net/dev describes the container, not the router. Interface bytes and packets come from the RouterOS API and are merged by the collector, not interpolated. privileged=yes does not change that.

Every write listed before it is made

Current release: 1.6.1, · Changelog

Download the archive for your platform from the release, or build the CLI from a checkout with make build. The router needs RouterOS 7.24 or later — the container step writes privileged=, an attribute earlier 7.x releases reject — with the container package and device-mode container=yes, which MikroTik gates behind a reset-button press or a power cycle. arm64, arm and x86_64; not MIPS, not TILE.

  1. mikroscope doctor

    Read-only preflight that names the fix for anything missing, then what the running agent's ring shows: a layer-2 loop, STP churn, a link flap or softnet drops.

  2. mikroscope plan

    Every RouterOS command, nothing written.

  3. mikroscope install

    Doctor, confirmation, the writes, then a probe of the agent. The image comes from your own Go toolchain, from the published agent tar, or from the registry the router pulls it from.

  4. mikroscope status

    Ownership counts and the agent's health.

  5. mikroscope uninstall

    Removes and verifies.

What install writes to your router

  • the install manifest, a file mikroscope/<name>.manifest.txt on the install's disk that lists the options and every object below
  • a veth
  • one address
  • one interface-list membership, unless --iface-list none
  • one address-list entry, unless --addr-list none
  • an envlist
  • the image tar, deleted once the container is extracted, unless --remote-image has the router pull the image
  • the container, and its root mikroscope/<name> on the same disk

Every object carries the comment mikroscope:<name> (managed by mikroscope)

mikroscope plan prints every command before anything is written.

uninstall removes by exact tag plus identity, never by pattern, and fails naming the step if anything remains.

Quick install, step by step →

Tested on

The figures on this page come from one router. Tested on names it, with the RouterOS versions, the dates and the conditions of every run.

It also lists what has not been tested: other boards, traffic heavier than that router's ordinary load, and the sinks and builds that have not run on hardware. No rate is claimed for any other board.

Cost scales with core speed, source set and ring size. Measure it on your own router before you budget for it.

Where to go next