
Sechzig Container auf einem Server
Eine Bare-Metal-Box führt Dutzende bis Hunderte von Hoody-Containern aus. KSM und BTRFS-Dedup machen die Marginalkosten nahezu null.
Poste am Montag einen Cron-Eintrag mit expires_at auf Freitag 09:00. Der Job pinged dein Telefon vier Tage lang alle 30 Minuten und löscht sich dann in dem Moment, in dem die Schicht endet. Der nächste On-Call postet seinen. Kein PagerDuty-Schedule, keine geteilte Scheduler-Config, keine Kalendererinnerung zum Deaktivieren.
der Eintrag, der m.dossantos pinged, existiert nur, solange m.dossantos On-Call ist
Drei Punkte in der Woche. Die Existenz des Cron-Eintrags spiegelt die Schicht exakt wider — kein Overlap, keine Lücke, keine übrig gebliebene crontab-Zeile.
Ein curl mit Schedule */30, command auf hoody-notifications/push/me, und expires_at = Freitag 09:00:00Z. Server gibt id e7d3 zurück.
Vier Tage lang, alle 30 Minuten, läuft der Eintrag und pinged hoody-notifications. Nur dein Gerät. Der Team-Channel bleibt ruhig.
Um 09:00:00Z löscht der Cron-Service e7d3. Der 09:30-Tick hat nichts zu feuern. Der nächste On-Call hat seinen schon gepostet.
Jeder On-Call schreibt einen POST, wenn seine Schicht beginnt. Das expires_at-Feld ist das gesamte Übergabeprotokoll — der Cron-Service erledigt das Aufräumen, auf die Sekunde genau.
Das ganze Rotationsprotokoll sind zwei HTTP-Calls pro Woche. Der On-Call postet am Montag, listet am Freitag, sieht, dass der Eintrag schon weg ist. Es gibt keine geteilte Schedule-Datei, in die man mergt.
# 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
Kein geteilter Scheduler-Service ist beteiligt. Der Cron-Eintrag gehört dem Engineer; nichts am Setup des nächsten On-Calls hängt davon ab, dass der vorige aufgeräumt hat.
Ein On-Call-Eintrag, dem seine eigene Lebenszeit gehört, stoppt drei Klassen von Fehlern, die PagerDuty-Configs und Kalendererinnerungen nicht stoppen können.
Weil das command des Eintrags auf deinen persönlichen Notify-Endpoint zeigt, gehen Eskalationen für die Dauer deiner Schicht an dein Telefon, und nur das. Kein versehentlicher Team-Channel-Spam um 3 Uhr nachts.
Es gibt keine escalation_policy.yaml, die jeder anfasst. Jeder Engineer besitzt seinen Eintrag. Zwei On-Calls in verschiedenen Zeitzonen können nicht durch das Editieren derselben Datei in Konflikt geraten.
Wenn am Freitag 09:00 die Schicht wechselt, fragst du nicht „Moment, krieg ich die noch?" Der Eintrag ist schon weg. Die Übergabe zu verifizieren ist ein GET, der eine Zeile weniger zurückgibt.
Zahlen kommen aus der Hoody Cron API. Echte Limits, keine erfundenen.
Auto-Expiration läuft gegen die Systemuhr. Ein 09:00:00Z expires_at löscht innerhalb derselben Minute, in der der Cron-Tick feuert — kein 5-Minuten-Janitor-Lag.
Standard-5-Feld-Cron-Ausdrücke plus @hourly / @daily / @weekly Makros. */30 * * * * ist es, was während deiner Schicht alle 30 Minuten feuert.
Jeder System-User hat seine eigene crontab. Der Eintrag des nächsten On-Calls lebt unter seinem eigenen /users/[name]/entries — nie deiner.
Limits laut Hoody Cron API: verwaltete Einträge sind JSON-CRUD mit UUIDs und expires_at; Raw-crontab-Zugriff pro User verfügbar; Per-User-crontab-Isolation ist eingebaut.
Wenn die Schicht endet, endet auch der Cron-Eintrag — automatisch.
Die Standardtools, zu denen du greifst, wenn du On-Call-Rotationen willst. Jedes berechnet dir einen Service, ein Config-Repo und ein Übergaberitual. Ein Cron-Eintrag mit expires_at berechnet dir einen POST.
Hör auf, am Freitagmorgen crontab-Zeilen zu deaktivieren. Setz expires_at am Montag und vergiss es.