
Sesenta contenedores en un servidor
Un servidor bare-metal ejecuta decenas a cientos de contenedores Hoody. KSM y dedup BTRFS hacen que el costo marginal sea casi cero.
Publica una entrada cron el lunes con expires_at puesto al viernes a las 09:00. El job avisa a tu teléfono cada 30 minutos durante cuatro días, y se elimina solo en el instante en que termina el turno. La siguiente persona de guardia publica la suya. Sin programación de PagerDuty, sin config de scheduler compartida, sin recordatorio en el calendario para desactivarla.
la entrada que avisa a m.dossantos solo existe mientras m.dossantos está de guardia
Tres puntos en la semana. La existencia de la entrada cron sigue al turno con exactitud — sin solapes, sin huecos, sin línea de crontab residual.
Un curl con schedule */30, command apuntando a hoody-notifications/push/me y expires_at = viernes 09:00:00Z. El servidor devuelve id e7d3.
Cada 30 minutos durante cuatro días la entrada se ejecuta y hace ping a hoody-notifications. Solo a tu dispositivo. El canal del equipo permanece en silencio.
A las 09:00:00Z el servicio de cron borra e7d3. El tick de las 09:30 no tiene nada que disparar. La siguiente persona de guardia ya ha publicado la suya.
Cada persona de guardia escribe un POST cuando empieza su turno. El campo expires_at es el protocolo de relevo entero — el servicio de cron hace la limpieza, al segundo.
Todo el protocolo de rotación son dos llamadas HTTP por semana. Quien está de guardia publica el lunes, lista el viernes y comprueba que la entrada ya no está. No hay archivo de programación compartida en el que hacer merge.
# monday 09:00 — i'm on call until friday 09:00 curl -X POST \ https://oncall.containers.hoody.com/users/me/entries \ -H "Content-Type: application/json" \ -d '["schedule":"*/30 * * * *","command":"curl -fsS hoody-notifications/push/m.dossantos","comment":"on-call wk19","expires_at":"2026-05-08T09:00:00Z"]' # response HTTP/1.1 201 Created { "id":"e7d3", "expires_at":"2026-05-08T09:00:00Z", "enabled":true }
# friday 09:01 — the next on-call took over curl GET https://oncall.containers.hoody.com/users/me/entries HTTP/1.1 200 OK [ // my entry e7d3 is gone — it expired // at 09:00 sharp. j.okafor's new // entry took over at 09:00:30. ] # no slack thread, no calendar reminder
Ningún servicio de scheduler compartido entra en juego. La entrada cron es propiedad del ingeniero; nada de la configuración del siguiente de guardia depende de que el anterior haya hecho limpieza.
Una entrada de guardia que controla su propio tiempo de vida frena tres clases de errores que las configs de PagerDuty y los recordatorios del calendario no pueden frenar.
Como el command de la entrada apunta a tu endpoint personal de notificación, las escaladas se dirigen a tu teléfono durante tu turno, y solo eso. Sin spam accidental al canal del equipo a las 3 de la mañana.
No hay un escalation_policy.yaml que toque todo el mundo. Cada ingeniero es dueño de su entrada. Dos personas de guardia en zonas horarias distintas no pueden chocar editando el mismo archivo.
Cuando llega el viernes a las 09:00 no preguntas «espera, ¿sigo recibiendo esto?». La entrada ya no está. Verificar el relevo es un GET que devuelve una fila menos.
Las cifras vienen de la API de Hoody Cron. Límites reales, no inventados.
La auto-expiración corre contra el reloj del sistema. Un expires_at 09:00:00Z se borra dentro del mismo minuto que dispara el tick de cron — sin retraso de 5 minutos del limpiador.
Expresiones cron estándar de 5 campos más macros @hourly / @daily / @weekly. */30 * * * * es lo que se dispara cada 30 minutos durante tu turno.
Cada usuario del sistema tiene su propio crontab. La entrada del siguiente de guardia vive en su propio /users/[name]/entries — nunca toca la tuya.
Límites según la API de Hoody Cron: las entradas gestionadas son CRUD JSON con UUIDs y expires_at; el acceso al crontab raw está disponible por usuario; el aislamiento del crontab por usuario está integrado de fábrica.
Cuando termina el turno, también termina la entrada cron — automáticamente.
Las herramientas a las que sueles recurrir cuando quieres rotaciones de guardia. Cada una te cobra un servicio, un repo de configuración y un ritual de relevo. Una entrada cron con expires_at te cobra un POST.
Deja de desactivar líneas de crontab los viernes por la mañana. Pon expires_at el lunes y olvídate.