Capacidad · lo que crece en una instancia y cómo se limita
Para qué. Un pub no se llena de golpe: se llena por una pieza que nadie miraba. Esta página es el inventario único de todo lo que crece en disco y en memoria, quién lo hace crecer, qué límite tiene y cómo se mide. Las piezas tienen además su detalle propio (
HUB-PROTOCOL.md§6,ECOIN-PROTOCOL.md§6); aquí está la vista de conjunto.Regla. Si añades una pieza que escribe en disco, añade su fila y su medida. Una pieza sin fila es la que llenará el disco.
1. Medir
bash devops/scripts/capacity.sh # el host de la instancia, por SSH · solo lectura
bash devops/scripts/capacity.sh --local # el stack local
bash devops/scripts/capacity.sh --json # una línea para un journalCada fila sale con un estado: ok, AVISO (pasa su presupuesto, o no tiene límite donde debería tenerlo) o ? (no se pudo medir). Sale con 0 si todo está bien, 1 con avisos, 2 si un disco pasa el umbral duro y 3 si algo no se pudo medir. deploy-status.sh lo resume.
Los presupuestos son umbrales de aviso, no límites: se ajustan por entorno (CAP_*, ver la cabecera del script) y se fijan con la medida del host, no a ojo. El límite, cuando existe, lo pone la pieza: el compose, la config del nodo o nginx.
2. Inventario
Por nodo de Oasis (pub, HUB, bots)
| Qué crece | Dónde | Quién lo hace crecer | Límite | Al pasar el presupuesto |
|---|---|---|---|---|
| Log | ssb-data/db2/log.bipf (Oasis ≥ 1.2) o flume/log.offset | la replicación: todo feed a hops saltos | friends.hops y friends.dunbar del ssb-config del nodo. No se poda | bajar hops o dunbar es una decisión de red: cambia a quién se replica |
| Índices | ssb-data/db2/indexes, db2/jit | el log | ninguno; son derivables (se regeneran borrándolos, con el nodo parado) | crecen con el log: se actúa sobre el log |
| Blobs | ssb-data/blobs | la replicación, lo que pide el visor y, desde 1.3.8 en un nodo pub: true (el pub; el bot con el motor encendido), el prefetch del sbot (blob_prefetch.js): cada blob que referencia un mensaje nuevo de un autor al que sigue, y al arrancar los de los últimos ssbLogStream.limit mensajes | backend (HUB, bots): blobCache.pubMaxMB en su oasis-config.json; lo fija pub/scripts/regen-node-configs.js. pub (solo sbot, sin recolector): hub-disk.sh prune-blobs --node pub | subir el techo o podar. Un blob borrado se vuelve a pedir a la red si alguien lo solicita |
| Snapshots | ssb-data/oasis/content/snapshot*.oasissn | pub: su propio entrypoint, cada OASIS_PUB_SNAPSHOT_HOURS horas. HUB y bots: nadie, con OASIS_SNAPSHOT=off | techo SNAPSHOT_MAX_MB (por encima no se publica y queda el anterior). Crece con el log | subir el techo, o dejar de ofrecerlo: OASIS_PUB_SNAPSHOT_HOURS=0 y recrear el pub |
| Logs de la aplicación | bind de /app/logs | el nodo | ninguno | vaciar con el nodo parado |
| Log de Docker | /var/lib/docker/containers/… | la salida del contenedor | logging del compose (max-size × max-file) en todos los servicios | un servicio sin logging es un aviso: no tiene techo |
| Capa del contenedor | /tmp (subidas, descarga de un snapshot) y /app/src/maps/cache | el backend | ninguno; se vacía al recrear el contenedor | recrear el nodo en la misma versión no publica nada |
| Memoria | — | el nodo; en el pub, también la construcción del snapshot; tras recrear, el reindexado de db2 | mem_limit y memswap_limit iguales en todos los nodos (D-O41; sin memswap_limit, Docker concede además otro tanto en swap y el límite no es límite) | subir el límite solo tras medir el pico; un nodo que llega al límite se reinicia (OOM-kill de cgroup, journalctl -k) |
Del host
| Qué crece | Dónde | Límite | Al pasar el presupuesto |
|---|---|---|---|
| Disco de datos y disco raíz | — | umbral blando 75 %, duro 90 % | por encima del duro no se construye ni se despliega |
| Memoria del host | /proc/meminfo (MemAvailable) | la RAM de la máquina. Los límites de los nodos suman más que ella (ECOIN §7): el reparto real lo decide el uso | presupuesto CAP_RAM_MB de disponible; por debajo, bajar un límite (HUB §7, orden de rebajas) o sacar del host lo que no es del pub |
| Swap | /swapfile en el disco raíz (D-O41: en Scriptorium el volumen de datos tiene 20× más latencia, medido en /proc/diskstats); vm.swappiness=10 (/etc/sysctl.d/90-oasis-swap.conf). Lo crea bootstrap-debian13-base.sh y lo comprueba verify-debian13-base.sh (check_swap) | el kernel, solo bajo presión | es red de seguridad para picos, no memoria: swap usada en reposo por encima de CAP_SWAP_PCT = la máquina es pequeña o un límite es alto. Sin swap, un pico mata un nodo |
| Imágenes y caché de build | /var/lib/docker | se podan en cada deploy (UPGRADE-PROTOCOL.md §4, paso 2) | docker image prune -f · docker builder prune -f |
| Restos de rollback | src.old-*, src-*.tgz, tags de imagen | uno por ciclo; se retiran al sustituirlos el siguiente | UPGRADE-PROTOCOL.md §4, paso 2 |
| Caché HTTP del visor | bind de /var/cache/hub | max_size e inactive de nginx | hub-disk.sh prune-cache |
| Cadena de ecoind | datos de ecoind | ninguno: no se puede podar | proyectar su crecimiento; es el dato que decide el tamaño del disco |
| Backups | en el host y en la máquina operadora | en el host, ECOIN_BACKUP_KEEP; en la máquina operadora, a mano | moverlos a almacenamiento cifrado fuera de la máquina (AGENTES.md §2.7) |
3. Lo que hace solo un nodo (Oasis ≥ 1.2)
Un backend trae temporizadores que tocan el disco sin que nadie lo pida:
| Temporizador | Cuándo | Qué hace | En esta arquitectura |
|---|---|---|---|
| Recolector de blobs | a los 5 min y cada 6 h | por encima del techo, borra los blobs ajenos menos usados de más de 24 h. Protege los propios, los fijados y los recientes | activo en HUB y bots con el techo de su config. Con el valor de upstream (pubMaxMB = 0) no haría nada |
| Construcción de snapshots | a los 2 min y cada 6 h, en un backend público | carga el log entero en memoria, dos veces, y escribe dos ficheros | apagado con OASIS_SNAPSHOT=off. El del pub lo construye su entrypoint (pub/tools/snapshot-build.js), con memoria constante |
| Limpieza de envíos de ficheros | a los 2 min y cada 12 h | borra los trozos de los envíos propios caducados | no hace nada en un nodo de soporte: no envía ficheros |
Guardián de feeds (feed_guard.js, sbot, ≥ 1.3.8) | al arrancar (valida el feed propio) y en cada conexión con un par | compara el feed propio con la copia del par; si el par tiene más cola, la adopta; si tiene otra, borra la cola local y republica (sin interruptor) | activo en pub, HUB y bots. Con un feed coherente no escribe nada: devops/scripts/feed-guard-status.js → lastRepair: null (UPGRADE §3.4, §4) |
Prefetch de blobs (blob_prefetch.js, sbot, ≥ 1.3.8) | con cada mensaje nuevo y al arrancar | blobs.want de lo que referencian los autores seguidos (arriba, fila de blobs) | solo con pub: true: el pub (sigue a sus habitantes) y el bot con el motor encendido (sigue solo al pub). Disco del pub: capacity.sh lo mide; hub-disk.sh prune-blobs --node pub lo poda |
| Publicaciones programadas (≥ 1.3.8) | con cada GET de un backend no público | publica blogs, podcasts, eventos, encuestas y votaciones cuya fecha ha llegado (scheduled.json) | solo lo que alguien programó desde la GUI: en un bot, nada (U5 lo mide: Δ0) |
Salas en clearnet (syncClearnetRooms, HUB, ≥ 1.3.8) | a los 20 s y cada 60 s, solo en un backend público | se une como oyente (RPC al plugin de teléfono) a las salas cuyo autor marcó rooms en clearnet, y las retransmite a quien pida /c/rooms/<id>/(live·sound) | CPU del HUB por sala viva (mezcla de sonido en JS) y red de salida por espectador (§4). Unirse no publica |
Ninguno publica en SSB, salvo el guardián de feeds cuando repara (por eso se mide) y las publicaciones programadas (solo lo programado).
4. Picos
- Migración del log (primer arranque en Oasis 1.2): conviven el log viejo y el nuevo. Hace falta libre el doble del log de cada nodo, además de la copia en frío previa.
- Build de la imagen: cada reconstrucción deja capas viejas hasta la poda.
- Construcción del snapshot: escribe un
.tmpjunto al fichero vigente antes de sustituirlo. - Reindexado de db2 (tras recrear un nodo, o tras borrar
db2/indexes): el heap de node sube hasta--max-old-space-sizemientras dura. Es el pico que fijamem_limit(1,5 × pico, HUB §7) y el que el swap del host absorbe si coinciden dos nodos. - Salas en clearnet (Oasis ≥ 1.3.8, HUB): el HUB retransmite a visitantes web el audio (
wavsin fin, ≈ 128 kbit/s) o el vídeo (multipartJPEG, ≈ 1,6 Mbit/s) de cada sala marcada en clearnet, a hastaCLEARNET_ROOM_WATCHERS_MAX(50) espectadores por sala: es red de salida del VPS (10 espectadores de vídeo ≈ 16 Mbit/s). Nginx no bufferiza ni cachea esos flujos (locationpropia). Si el custodio no lo quiere, esalocationresponde 404 (UPGRADE §4). - PDF en el visor (Oasis ≥ 1.3.8, HUB):
/c/pdf/pagerasteriza páginas conmupdf(wasm) en unworker_threadcon cola, tope de memoria (PDF_WORKER_HEAP_MB) y 60 s por llamada: CPU del HUB por página, en serie. Nginx cachea cada página 1 d por URL (el backend mandaprivate; lalocationlo ignora: en/csolo sale contenido clearnet). - Centralita del pub (Oasis ≥ 1.2.2,
HUB-PROTOCOL.md§14): no toca disco; gasta red y algo de memoria del pub. Cada llamada retransmitida son unos 80 kbit/s por sentido (entran y salen por el pub). En una sala, cada persona que habla cuesta 80 kbit/s por oyente: con el aforo fijado (phone.roomMax, 12) unos 0,9 Mbit/s de salida por hablante; con el de fábrica (50), unos 4 Mbit/s. El pub retiene como mucho 2 000 tramas por miembro atrasado. El número de salas y de llamadas simultáneas no tiene techo en el plugin: lo acota a quién sirve el pub (solo a feeds que sigue). Son cifras leídas del código, no medidas.