
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.
Tus clientes escriben la expresión cron. Tú haces POST al crontab de su contenedor. No hay cola compartida que repartir, ni intervalo mínimo que imponer, ni ticket de soporte por «por qué mi job no se ejecutó el lunes pico».
Una página de ajustes real orientada al cliente — programaciones editadas por el tenant, parseadas por su contenedor.
Tu página de ajustes pinta un campo de input. Su contenedor de tenant expone una API de Cron. El submit reenvía un POST. Sin scheduler global, sin lógica de filtrado por tenant, sin tope de «máximo 100 jobs entre todos los clientes».
// el submit del formulario reenvía la expresión del cliente sin cambios
POST https://acme-cron.hoody.com/users/root/entries
Content-Type: application/json
{
"schedule": "0 9 * * 1-5",
"command": "/jobs/sync_crm.sh",
"comment": "Sync Salesforce contacts",
"enabled": true
}HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "sch_8a3f1c",
"schedule": "0 9 * * 1-5",
"next_run": "2026-05-04T09:00:00Z",
"enabled": true
}
// la programación está ahora en el crontab de este tenant y en ningún otro sitioEl servicio Hoody Cron corre dentro de cada contenedor de tenant con entradas gestionadas y aislamiento por usuario. La programación vive donde corre el trabajo.
Cuando la programación vive junto al trabajo, las reglas de la programación multi-tenant cambian. Las restricciones son locales. El radio de impacto es local. Las funcionalidades son locales.
No hay un thread pool global por el que pelear. Tu tenant más exigente corre cada minuto y nunca mata de hambre a los tranquilos — no están en el mismo crontab.
Dejas de ser el portero de «¿está */1 * * * * permitido para tu tier?». Su contenedor, su cron, su factura de CPU. Tu inbox de soporte se vacía.
Haz un snapshot del contenedor del tenant y haces snapshot del crontab. Vuelve atrás, restaura, bifurca — las programaciones van con él. Sin estado externo de scheduler que sincronizar.
La diferencia se nota en tres sitios: la experiencia del cliente, tu carga de soporte y la superficie de ingeniería.
La versión con scheduler compartido de esta funcionalidad es un mar de matices. La versión BYO es una caja de input de cinco campos.
Tres números que cambian el día que dejas de tener una cola global. Cada uno mapea a una funcionalidad que ya no tienes que escribir ni operar.
Sin intervalo mínimo limitado por tier, sin máximo de jobs por tenant, sin ruedas de fair-share. El contenedor es el límite.
El cliente escribe, tú reenvías, el contenedor parsea. El submit de la página de ajustes es una sola llamada REST, no una orquestación.
minuto · hora · día-del-mes · mes · día-de-la-semana. Más macros (@hourly, @daily). POSIX estándar, no tu DSL.
Las cifras reflejan el modelo BYO ligado al contenedor — las entradas cron reales escalan con la CPU de cada contenedor y el plan del cliente.
La expresión cron del cliente es del cliente, no algo que tú tengas que validar contra una cola global.
Las piezas de infraestructura que un cron BYO ligado al contenedor jubila silenciosamente.
Deja de ser el portero de la programación de otra persona. Dales el campo cron, dale el trabajo a su contenedor.