The rate ceiling
The question this page answers is the one worth asking before trusting any of it: how fast can it sample before it starts losing data?
On the reference device the answer is that it does not, up to the CLI’s own 100 Hz cap, with every source read on every tick. That is not an extrapolation from the 10 Hz figure. It is five runs.
The five runs
Section titled “The five runs”Every figure is from the agent’s own cgroup and /metrics, with the full source set. Each row is
one window with the ring already full:
Measured on RB5009UG+S+ · 4 × 1.4 GHz Cortex-A72 · RouterOS 7.24.2 · · 60 s windows at steady state (ring full), full source set, collector forwarding to a file, a Prometheus exposition and InfluxDB 3 at once
| rate | floors | CPU of one core | µs/ | RSS | slipped ticks | gaps / |
|---|---|---|---|---|---|---|
| 10 Hz (default) | default | 2.85 % | 2 856 | 31.3 MiB | 0 | 0 / 0 |
| 50 Hz | default | 10.13 % | 2 026 | 51.9 MiB | 0 | 0 / 0 |
| 100 Hz | default | 17.81 % | 1 781 | 76.5 MiB | 5 (0.08 %) | 0 / 0 |
| 50 Hz | FLOOR_HZ=50 | 22.47 % | 4 494 | 60.6 MiB | 6 (0.20 %) | 0 / 0 |
| 100 Hz | FLOOR_HZ=100 | 43.95 % | 4 395 | 79.6 MiB | 14 (0.23 %) | 0 / 0 |
Scroll sideways to see every column
FLOOR_HZ means every source is read on every tick, with no per-source floor at
all — the worst case the agent can be asked for.
Memory differs by row because the ring does. The 10 Hz row is the install
default (300 s ring, --mem-limit-mb 40 --memory-max 64M); the 50 Hz rows used --buffer 120 --mem-limit-mb 64 --memory-max 96M and
the 100 Hz rows --buffer 120 --mem-limit-mb 80 --memory-max 128M. Give the agent’s garbage collector room or the cost
jumps for reasons that have nothing to do with the rate.
Two things in that table worth reading twice
Section titled “Two things in that table worth reading twice”Per-sample cost falls as the rate rises
Section titled “Per-sample cost falls as the rate rises”A sample costs 2 856 µs at 10 Hz against 1 781 µs at 100 Hz. That is not a
paradox, it is the floors working: the expensive sources are amortised over more samples.
/proc/slabinfo, one of the expensive sources (13.8 kB), is read every 2nd tick at 10 Hz and every
17th at 100 Hz, so an average sample costs less while the rate of slabinfo reads
stays near its 6 Hz floor either way (5 Hz at 10 Hz, about 5.9 Hz at 100 Hz).
With FLOOR_HZ there is no amortisation to be had and the per-sample cost is
flat — 4 494 µs at 50 Hz and 4 395 µs at
100 Hz — so CPU scales linearly with the rate: 22.47 %, then 43.95 %.
A slipped tick is not a lost sample
Section titled “A slipped tick is not a lost sample”The sample is still produced and still delivered, carrying its real dt_ns, so
any rate computed from it stays correct. It is a smear, not a hole, and
mikroscope_ is where you see it. At 100 Hz with
everything on every tick, 99.5 % of ticks still landed within 11 ms of a 10 ms
period and the worst was 15 ms.
What binds is the read, not the CPU
Section titled “What binds is the read, not the CPU”At the default floors a whole tick’s sources are read in under 2 ms for 97.5 % of
samples at 100 Hz, comfortably inside a 10 ms period. FLOOR_HZ pushes 1.4 %
of reads past 5 ms, and those are the ticks that slip. The CPU headroom is
larger than the timing headroom, which is why the ceiling is a statement about
I/O rather than about the A72.
What sampling faster actually buys
Section titled “What sampling faster actually buys”Not CPU-percent resolution. The jiffie is 10 ms, so at 100 Hz a sample holds either 0 or 1 busy tick and the per-sample busy ratio has two possible values. Above roughly 20 Hz the tick counters stop being a percentage and become an occupancy indicator; the PMU is the resolution from there.
What a higher rate does buy is everything that is not jiffie-quantised — softnet packet counts, interrupt deltas, PMU counters, the kernel log’s own timestamps — and a tighter bound on how long a burst can hide between two samples.