Coste del agente
Con los valores por defecto de la instalación — 10 Hz, los suelos por fuente por defecto, anillo de 60 s — el agente le cuesta a un MikroTik RB5009 un 2,69 % de un núcleo y un 13,2 MiB de RSS, leído desde su propio cgroup:
Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · ventanas de 300 s en régimen estacionario (con el anillo ya lleno), conjunto completo de fuentes, la configuración que se envía —anillo de 60 s, límite de memoria derivado de él y el tope de contenedor de serie de 64M— con el colector reenviando a InfluxDB 3
El agente publica su propio coste en cada muestra, y la CI comprueba el presupuesto de tamaño de la imagen.
Presupuesto
Sección titulada «Presupuesto»El presupuesto es ≤ 2 % de un núcleo, ≤ 16 MiB de RSS, ≤ 8 MiB de imagen. La imagen arm64 publicada de 1.2.1 mide 6,38 MiB (6 690 304 B, medido sobre el artefacto de la versión el 2026-09-24); la de 1.0.0 medía 6,1 MiB, la cifra que dan las notas de esa versión. Los otros dos dependen de la cadencia y de cuánto le pidas leer al agente, así que la respuesta es una tabla y no un número: Techo de muestreo es esa tabla.
La memoria está dentro del presupuesto y la CPU no. 13,2 MiB frente a los 16 MiB que pide el presupuesto, y un 2,69 % frente al 2 %, con todas las fuentes leídas, entre ellas los tiempos de perf, buddyinfo, los contadores ECC de MTD, slabinfo, el log del kernel y los eventos de cgroup. El tráfico por interfaz no está en ese conjunto: el contenedor no lo ve, y viene de la capa de la API.
La campaña del 2026-09-15 estaba por encima en los dos. Su anillo guardaba 300 s en vez de 60 y su límite de memoria era un 40 MiB fijo que nunca apretaba, lo que dejaba al mismo agente en 31,3 MiB; ninguna de las dos cifras decía nada sobre la cadencia. Nada del muestreo cambió entre las dos campañas: la CPU pasó del 2,85 % al 2,69 %, que es el ruido entre dos ventanas.
Bucle de shell como base
Sección titulada «Bucle de shell como base»El presupuesto dice lo que se le permite costar al agente. La comparación que suele querer quien lee es contra la forma obvia: un bucle de shell de busybox. El 2026-09-11, en el mismo router, un bucle que leía a 10 Hz el conjunto de ficheros que leía entonces el agente costó 2,40–2,48 % de un núcleo, mientras que las lecturas en sí rondaban los 0,77 ms por muestra.
Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · un bucle de shell de busybox leyendo a 10 Hz el conjunto de ficheros que leía entonces el agente, siete ficheros, con un fork por iteración, en un contenedor del router; dos ejecuciones de 60 s
Así que la mayor parte del coste del bucle de shell no estaba en leer. Paga un fork por iteración y el agente no paga ninguno: un proceso arranca, abre sus ficheros una vez y los deja abiertos, y por eso el agente es un binario y no un script. Aun así, las dos cifras no se pueden poner una al lado de la otra. Hoy el agente lee mucho más — perf, buddyinfo, los contadores ECC de la MTD, slabinfo, el log del kernel — y el bucle no se ha vuelto a medir con ese conjunto, así que no se puede comparar con 2,69 %.
Quien tira del agente se suma a eso. Además del colector y de record, un doctor independiente
lee el anillo una vez, en una sola petición: el anillo entero cuando no guarda más de 10 000
muestras, y si no las 10 000 más recientes. Con los valores por defecto es el anillo entero de 60 s,
unos 1,9 MB a 10 Hz, y esa petición se sirve en el núcleo del muestreador; el coste de esa lectura en
el RB5009 no se ha medido.
Límite de memoria
Sección titulada «Límite de memoria»El error más caro disponible aquí es dar al proceso menos memoria de la que su anillo necesita. El
recolector de basura de Go responde a un límite blando ajustado ejecutándose más a menudo, y el
coste de CPU se dispara por un motivo que no tiene nada que ver con la cadencia de muestreo. El
anillo guarda líneas ya codificadas en vez de structs por la misma razón. Si subes --buffer o la
cadencia, sube con ellos --mem-limit-mb y el --memory-max del contenedor; las opciones que usó
cada ejecución están junto a ella en Techo de muestreo.
install deriva MEM_LIMIT_MB del anillo: cadencia × buffer × el tamaño de línea, por 2,5, con un
mínimo de 16 MiB y un máximo de tres cuartos de memory-max, así que la instalación por defecto
escribe 16 para un anillo de 60 s a 10 Hz. El factor está medido. En el RB5009 (RouterOS 7.24.2,
10 Hz, un anillo de 300 s, todas las fuentes activas) el 2026-09-17, cuatro límites en cuatro
ventanas de unas 12 000 muestras cada una:
| límite | múltiplo del anillo | RSS | CPU por muestra | Lo que costó |
|---|---|---|---|---|
| 40 MiB | 4,0× | 32,9 MiB | 2 657 µs | el límite nunca aprieta |
| 24 MiB | 2,4× | 26,3 MiB | 2 780 µs | ningún coste medible |
| 21 MiB | 2,1× | 23,5 MiB | 3 250 µs | +22 %, y subiendo |
| 18 MiB | 1,8× | 20,4 MiB | 14 800 µs | +457 %, el peor tick de 52 ms |
Desliza en horizontal para ver todas las columnas
Las filas son las que registra el comentario de memLimitRingFactor
en internal/. El factor de 2,5× serían 25 MiB a 300 s; la ventana medida
más cercana fue la de 24 MiB, y ninguna de las cuatro ventanas se anotó con su dispersión. El mismo
precipicio se midió desde el otro lado el 2026-09-12: un 9,38 % de un núcleo
con 14 MiB frente a un 1,39 % con margen, las dos con el anillo lleno.
El análisis no es donde se va el tiempo. Analizar los siete ficheros globales de /proc más un
delta costó 27 µs y 239 asignaciones por muestra en el equipo de desarrollo amd64 (Go 1.27.1, tres
ejecuciones, 26,7–27,5 µs, 2026-09-11). En el Cortex-A72 del RB5009 un tick entero — con
temporizadores, JSON y el recolector de basura incluidos —
cuesta 2 685 µs a 10 Hz con los suelos por defecto, y
las seis ejecuciones lo dan a cada cadencia. El análisis por sí
solo no se midió en el A72.
Coste de SSH
Sección titulada «Coste de SSH»Cada conexión SSH le cuesta al RB5009 un 20–27 % de CPU mientras dura.
Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.1 · · una conexión ssh, mientras dura
Esa lectura es anterior al agente y se tomó con RouterOS 7.24.1. Con 7.24.2, el 2026-09-11, el mismo
coste apareció en /tool profile como un 17–33 % en una o dos instantáneas, no en una ventana
medida. Por eso la CLI agrupa todas las lecturas en una sola conexión — doctor es una, status es
una, las preguntas de estado de install son una — y cada escritura suma otra, más la subida por
scp. SSH nunca es un camino de datos: record y forward llegan al agente por HTTP o por la API
de RouterOS.
Coste de la capa API
Sección titulada «Coste de la capa API»Medido con el propio profiler de RouterOS, una vez con el colector parado y otra con él haciendo una ronda cada segundo:
Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · /tool profile duration=60s cpu=total, una vez con el colector parado y otra con él en marcha con --interfaces bridge,; descartadas las cinco primeras instantáneas de un segundo de cada perfil, porque llevan la conexión SSH que lo pidió
| Fila del perfil | Colector parado | Colector en marcha |
|---|---|---|
| total | 5,93 % | 6,04 % |
interface-mgmt |
0,40 % | 0,87 % |
config-db |
unos 0 % | 0,15 % |
Desliza en horizontal para ver todas las columnas
El total se mueve 0,11 puntos, dentro del ruido del tráfico de un minuto; las dos filas que responden
a las preguntas de la capa se mueven juntas medio punto. En ninguno de los dos perfiles aparece una
fila de proceso api: el proceso de la API hace de intermediario y el trabajo cae en el subsistema
que responde. Así que una capa que hace una ronda por segundo le cuesta al router en torno al 0,5 %
de su CPU total. Esa tabla es un único perfil de 60 s por condición, sin dispersión.
Una configuración mayor se midió como A/B en el mismo router el 2026-09-19, el día de la
actualización de RouterOS que lo dejó en 7.24.4; no quedó registrado sobre qué versión corrió el A/B
en sí. Todas las interfaces salvo lo en --interfaces (16) y --conntrack-every 10s, 8 min sin
ella frente a 14 min con ella: el cpu-load medio pasó de 7,12 % a 7,91 % y la ocupación media del
kernel de 7,70 % a 8,46 %, unos +0,8 puntos. Es una cota inferior, porque el tráfico del bridge bajó
de 48,0 a 38,9 Mbit/s entre las ventanas. El p50 de cpu-load se quedó en 6 y el p95 pasó de 16 a
18.
--conntrack-every pregunta /ip/: una llamada
tardó 1,3 ms con 6 212 entradas, la mediana de diez
llamadas; la más rápida tardó 1,1 ms y la primera 71 ms, en frío.
Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · la tabla de conexiones contada por la API binaria de RouterOS, /ip/, diez llamadas
Medir en tu router
Sección titulada «Medir en tu router»Nada de esto se traslada a una placa que no sea un RB5009: otro número de núcleos, otro reloj, otro kernel y otra flash lo mueven. El procedimiento son tres órdenes y lleva un minuto:
curl -s http://<collector host>:9124/metrics | grep -E 'self_cpu_usec_total|self_rss_bytes'sleep 60curl -s http://<collector host>:9124/metrics | grep -E 'self_cpu_usec_total|self_rss_bytes'La diferencia de self_cpu_usec_total dividida entre 60 000 000 es la fracción de un núcleo. O deja
que la shell haga la división, en tres minutos:
U=http://<equipo del colector>:9124/metricsget() { curl -s "$U" | awk -v k="$1" '$1==k{print $2}'; }c0=$(get mikroscope_self_cpu_usec_total); t0=$(date +%s)sleep 180c1=$(get mikroscope_self_cpu_usec_total); t1=$(date +%s)echo "$c0 $c1 $t0 $t1" | awk '{printf "%.2f %% of one core\n", 100*($2-$1)/1e6/($4-$3)}'Tres cosas que cabe esperar:
- El coste y la memoria suben hasta que el anillo se llena. Con el anillo por defecto de 60 s a
10 Hz el agente guarda 600 muestras ya codificadas; una cifra tomada en el primer minuto tras la
instalación se mide sobre un heap casi vacío y sale baja. Espera a que pase
BUFFER_Santes de citar una cifra de régimen estacionario. - Una instantánea lo exagera. Un
/snapshotde 60 s entrega unas 600 líneas, unos 1,9 MB, y elself.cpu_usde esas muestras incluye el coste de servirlas; leer el coste en instantáneas repetidas lo exagera más. mikroscope_slipped_totales el número que importa. Un muestreador que cuesta algo más pero nunca pierde ticks te está diciendo la verdad; uno que los pierde, no.
La dirección es la del colector, no la del agente: el agente no sirve ningún /metrics, y esos dos
contadores llegan al colector en cada muestra. Sin destino de Prometheus configurado, esos mismos dos
números son cpu_us y rss en mikroscope_self en InfluxDB, Telegraf, stdout y los almacenes SQL,
self.cpu_us y self.rss en los documentos de muestra de Elasticsearch, self.cpu_us y
self.rss_bytes en Graphite, y mikroscope.self.cpu.time / mikroscope. en
OTLP. Medida en una placa que no sea un RB5009, con la cadencia, la fecha y lo que hacía el router,
la cifra va en un
informe de placa.