
Sessenta contêineres em um servidor
Uma caixa bare-metal executa dezenas a centenas de contêineres Hoody. KSM e BTRFS dedup fazem o custo marginal próximo a zero.
Seus clientes digitam a expressão cron. Você faz POST no crontab do contêiner deles. Não há fila compartilhada para fair-share, intervalo mínimo para impor nem ticket de suporte sobre "por que meu job não rodou na pico de segunda".
Uma página de configurações de cliente real — agendamentos editados pelo tenant, parseados pelo contêiner dele.
Sua página de configurações renderiza um campo. O contêiner do tenant expõe uma Cron API. O submit encaminha um POST. Sem scheduler global, sem lógica de filtro por tenant, sem cap de "máximo 100 jobs entre todos os clientes".
// o submit do formulário repassa a expressão do cliente sem alterar
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
}
// o agendamento agora está no crontab deste tenant e em mais nenhum lugarO serviço Hoody Cron roda dentro de cada contêiner de tenant com entradas gerenciadas e isolamento por usuário. O agendamento mora onde o trabalho roda.
Quando o agendamento mora ao lado do trabalho, as regras do agendamento multi-tenant mudam. As restrições são locais. O raio de impacto é local. Os recursos são locais.
Não há thread pool global para brigar. O seu tenant mais exigente roda a cada minuto e nunca asfixia os silenciosos — eles não estão no mesmo crontab.
Você para de ser o porteiro do "o */1 * * * * é permitido para o seu plano?". O contêiner deles, o cron deles, a fatura de CPU deles. Sua caixa de entrada de suporte esvazia.
Faça snapshot do contêiner do tenant, e o crontab vai junto. Faça rollback, restore, fork — os agendamentos vão junto. Sem estado de scheduler externo para sincronizar.
A diferença aparece em três lugares: a experiência do cliente, sua carga de suporte e a área de superfície de engenharia.
A versão do recurso com scheduler compartilhado é um mar de ressalvas. A versão BYO é uma caixa de entrada de cinco campos.
Três números que mudam no dia em que você para de operar uma fila global. Cada um mapeia para um recurso que você não precisa mais escrever ou operar.
Adeus intervalo mínimo por plano, max-jobs-por-tenant, knobs de fair-share. O contêiner é o limite.
Cliente digita, você encaminha, o contêiner faz parse. O submit da página de configurações é uma chamada REST, não uma orquestração.
minuto · hora · dia-do-mês · mês · dia-da-semana. Mais macros (@hourly, @daily). POSIX padrão, não a sua DSL.
Os números refletem o modelo BYO atrelado ao contêiner — entradas cron reais escalam com a CPU de cada contêiner e o plano do cliente.
A expressão cron do cliente é do cliente, não sua para validar contra uma fila global.
Os pedaços de infraestrutura que um BYO cron preso ao contêiner aposenta em silêncio.
Pare de ser o porteiro do agendamento dos outros. Entregue o campo cron, entregue o trabalho ao contêiner deles.