
Soixante conteneurs sur un seul serveur
Une machine bare-metal exécute des dizaines à des centaines de conteneurs Hoody. La dédupplication KSM et BTRFS rend le coût marginal quasi nul.
Chaque nuit à 1h, une entrée cron fait un curl sur une URL exec. Le script lance votre SQL d'agrégation sur l'URL sqlite et écrit la table quotidienne. Pas de Postgres Airflow, pas de fichier DAG, pas de tableau de bord scheduler à 14 widgets, pas d'astreinte pour l'orchestrateur lui-même.
SELECT date_trunc('day', created_at) AS d,
count(*) AS n
FROM events
WHERE created_at >= 'today'
GROUP BY 1 -- the whole pipelineLE TABLEAU DE BORD EST L'ORCHESTRATEUR. UNE URL. UN PLANNING.
Toute la pipeline, c'est une entrée cron qui pointe sur une URL exec. L'entrée cron est un POST sur /users/root/entries. L'URL exec est un petit script qui ouvre l'URL sqlite, lance le SQL d'agrégation et renvoie les nouvelles lignes. Voilà tout le DAG.
// chaque nuit à 01:00 UTC
POST /users/root/entries
{
"schedule": "0 1 * * *",
"command": "curl -fsS https://exec.containers.hoody.com/scripts/rollup/run"
}// le corps entier de la pipeline
import { Database } from "bun:sqlite";
const db = new Database("events.db");
db.run(`INSERT INTO rollup_daily
SELECT date_trunc('day', created_at), count(*)
FROM events GROUP BY 1;`);
return { ok: true, rows: db.query("SELECT * FROM rollup_daily").all() };Si l'agrégat échoue, les logs cron le disent. Si vous devez rejouer la veille, vous appelez l'URL exec à la main avec un paramètre date. Pas de second système à apprendre, pas de base scheduler à maintenir vivante, pas de fichier DAG à committer. L'orchestrateur, c'est une entrée cron qui pointe sur une URL.
Le Hoody Kit livre le scheduler, le runtime et le stockage en simples services HTTP. La pipeline, c'est l'appel curl entre eux — rien d'autre.
hoody-cron stocke les plannings comme des ressources sur /users/root/entries. Pas de base de métadonnées Postgres à sauvegarder, pas de conteneur scheduler à garder en bonne santé, pas de dépôt DAG à déployer. POSTez une ligne, et le run se déclenche.
hoody-exec exécute le script d'agrégation à la demande sur exec.containers.hoody.com/scripts/rollup/run. cron fait le curl, reçoit un 200, log la réponse. Pas de file de workers, pas de broker, pas de graphe de tâches picklé.
Chaque appel exec renvoie les nouvelles lignes en JSON et est loggé par cron avec statut, timestamp et stdout. Backfills, échecs et retry vivent tous dans les deux mêmes URL — rien de plus à expédier vers un agrégateur de logs.
La pipeline, c'est deux URL et un paramètre date. Rejouer hier a la même forme que le run nocturne, juste avec ?date=2026-04-30 sur l'URL exec. Pas d'UI de replay, pas de bizarreries scheduler.
Si le run de 1h a renvoyé un non-2xx, l'enregistrement de dernier run de l'entrée sur hoody-cron montre le code de sortie et le corps de réponse capturé. Pas de service d'alerting séparé à câbler — GETez l'entrée et lisez-la.
Le script accepte un paramètre date. Passez la date d'hier et il recalcule la ligne d'agrégat de ce jour, remplaçant la cassée par un INSERT OR REPLACE. Une commande, pas d'UI de re-déclenchement DAG.
exec renvoie la ligne d'agrégat fraîchement écrite en JSON. Diffez-la contre ce que vous attendiez, puis passez à autre chose. Rien d'autre à vérifier — l'URL du tableau de bord sert la même table que vous venez d'écrire.
Trois nombres décrivent tout le système. Comparez-les avec à quoi ressemble un déploiement Airflow dans votre dépôt aujourd'hui.
minute, heure, jour-du-mois, mois, jour-de-la-semaine. Voilà toute la surface de configuration pour le moment où un run se déclenche.
un POST pour enregistrer le planning, un GET qui lance le script. Voilà toute la pipeline déployable.
pas de processus scheduler à garder en vie, pas de base de métadonnées, pas de pool de workers. Hoody Kit tient les plannings et lance le script.
Les chiffres décrivent le modèle cron + exec sur Hoody Kit. Votre pipeline existante a probablement plus de pièces mobiles ; c'est tout l'intérêt de la comparaison.
L'orchestrateur, c'est une entrée cron qui pointe sur une URL.
La couche d'orchestration s'effondre en un cron d'une ligne. Le DAG vit dans votre script.
Arrêtez de faire tourner un orchestrateur. Faites tourner une entrée cron.