Ein Cron-Job ist eine Aufgabe, die automatisch nach einem Zeitplan läuft; geplanter Cloud Code überträgt die Idee auf Serverless-Funktionen. Die Linie führt von Unix Version 7 über Vixie cron (1987) bis zu den Schedulern heutiger Plattformen, und das Modell hat sich kaum verändert: Ein Daemon wacht jede Minute auf, liest eine Tabelle aus Zeilen der Form Zeitplan + Befehl – die Crontab – und feuert, was passt. Verändert hat sich alles rund um das Modell: wo die Uhr lebt, was bei einem gescheiterten Lauf passiert und ob es überhaupt jemand bemerkt.
Das Wichtigste im Überblick
| Frage | Antwort |
|---|---|
| Die Syntax | Fünf Felder – Minute · Stunde · Tag des Monats · Monat · Wochentag |
| Die Untergrenze | Minutengenauigkeit; für Sekunden braucht es einen anderen Scheduler |
| Die Fallstricke | Sommerzeit überspringt und verdoppelt Läufe · die ODER-Regel für Monatstag und Wochentag |
| Die Zuverlässigkeitslücke | Klassisches cron: keine Wiederholungsversuche, kein Nachholen, kein Cluster, stilles Scheitern |
| Die moderne Form | Zeitplan als Plattformkonfiguration an einer Funktion – Uhr, Logs und Wiederholungen verwaltet |
Cron auf einem Bildschirm
┌ Minute (0–59) ┌ Stunde (0–23) ┌ Tag des Monats (1–31) ┌ Monat ┌ Wochentag (0–7)
* * * * * Befehl
0 2 * * * täglich um 02:00 */15 * * * * alle 15 Minuten
0 9 * * 1-5 werktags um 09:00 0 6,18 * * * 06:00 und 18:00
0 0 1,15 * * am 1. und 15. @daily = 0 0 * * *
@reboot einmal beim Start @hourly = 0 * * * *
crontab -e Tabelle bearbeiten crontab -l auflisten
crontab -ri entfernen (mit Rückfrage – bloßes -r löscht sie kommentarlos)
Das moderne Gegenstück – der Job im Code, der Zeitplan in einem Dashboard, der Client liest nur die Ergebnisse:
// JavaScript — Cloud Code (cloud/main.js)
// A scheduled job: defined in code, scheduled in the dashboard
Parse.Cloud.job('nightlyReport', async (request) => {
const since = new Date(Date.now() - 24 * 60 * 60 * 1000);
// Idempotent by date key: a rerun overwrites tonight's report, not duplicates
const existing = await new Parse.Query('DailyReport')
.equalTo('runDate', dateKey(new Date()))
.first({ useMasterKey: true });
const report = existing ?? new Parse.Object('DailyReport');
report.set('runDate', dateKey(new Date()));
report.set('summary', await summarizeOrdersSince(since));
await report.save(null, { useMasterKey: true });
request.message('Report written'); // shows in the dashboard's job status
}); // Flutter / Dart — Back4app Flutter SDK
// Clients consume what the schedule produces — no crontab in sight
final query = QueryBuilder<ParseObject>(ParseObject('DailyReport'))
..orderByDescending('runDate')
..setLimit(1);
final latest = (await query.query()).results?.first as ParseObject?;
print(latest?.get<String>('summary'));
// The report exists because a scheduled Cloud Job ran at 02:00 UTC —
// defined in code, scheduled in the dashboard, logged by the platform. // iOS / Swift — Back4app Swift SDK
// Clients consume what the schedule produces — no crontab in sight
let latest = try await DailyReport.query()
.order([.descending("runDate")])
.first()
print(latest.summary ?? "")
// The report exists because a scheduled Cloud Job ran at 02:00 UTC —
// defined in code, scheduled in the dashboard, logged by the platform. // Android / Kotlin — Back4app Android SDK
// Clients consume what the schedule produces — no crontab in sight
val query = ParseQuery.getQuery<ParseObject>("DailyReport")
query.orderByDescending("runDate")
query.limit = 1
val latest = query.find().firstOrNull()
println(latest?.getString("summary"))
// The report exists because a scheduled Cloud Job ran at 02:00 UTC —
// defined in code, scheduled in the dashboard, logged by the platform. Die Fallstricke, die die Manpage kennt
Vier Semantiken aus crontab(5), die fast jeden überraschen. Die ODER-Regel: Wenn sowohl Monatstag als auch Wochentag eingeschränkt sind, feuert der Job, sobald eines von beiden passt – 0 0 13 * 5 läuft am 13. und an jedem Freitag, nicht nur an Freitag, dem 13. Sommerzeit, wörtlich: Jobs, die in der “fehlenden Stunde” der Vorstellung liegen, laufen nie; Zeiten, die bei der Rückstellung doppelt vorkommen, laufen zweimal – planen Sie in UTC und halten Sie kritische Arbeit aus den lokalen frühen Morgenstunden heraus. Schrittweiten setzen an Feldgrenzen zurück: */90 im Minutenfeld kann nicht “alle 90 Minuten” bedeuten – der Zähler beginnt zu jeder Stunde neu; echte krumme Intervalle brauchen einen richtigen Scheduler. Die Minuten-Untergrenze: Der Daemon prüft einmal pro Minute; alles Feinere ist Aufgabe eines anderen Werkzeugs.
Die Zuverlässigkeitslücke
Klassisches cron ist ein Scheduler, kein Zuverlässigkeitssystem, und die Lücke hat eine klare Form: keine Wiederholungsversuche (ein gescheiterter Lauf bleibt gescheitert); kein Nachholen (eine Maschine, die um 02:00 schläft, überspringt den Lauf – anacron und die Persistenzoption der systemd-Timer gibt es genau deshalb); keine Antwort für Cluster (zwei Server mit derselben Crontab führen alles doppelt aus; ein einzelner Server ist ein Single Point of Failure); stilles Scheitern (die Ausgabe geht per Mail an ein lokales Konto, das niemand liest). Moderne Scheduler beantworten jede Lücke mit einer benannten Richtlinie: Misfire Policies (fire-now vs. skip bei Quartz), Concurrency Policies (allow/forbid/replace bei Kubernetes für überlappende Läufe) und Skip-Semantiken auf Basis einer Frist – und dokumentieren dabei ehrlich, dass verteilte Planung ungefähr einmal bedeutet: Ein Lauf kann gelegentlich doppelt erfolgen oder ganz ausbleiben. Daraus folgt die Disziplin, die beide Welten teilen: Geplante Jobs müssen idempotent sein – geschlüsselt auf ihre Periode (der Bericht in den Code-Tabs ist nach Datum geschlüsselt), damit ein erneuter Lauf überschreibt statt zu verdoppeln, und ein verpasster Lauf sich durch späteres Nachholen retten lässt.
Klassisches cron vs. systemd-Timer vs. verteilte Scheduler vs. geplante Funktionen
| Klassisches cron | systemd-Timer | Verteilt (Quartz-/K8s-Stil) | Geplante Cloud-Funktionen | |
|---|---|---|---|---|
| Lebt in | Der Crontab einer Maschine | Einer Maschine, Unit-Dateien | Einem Cluster | Der Plattformkonfiguration an einer Funktion |
| Nachholen | Keines (anacron rüstet es nach) | Persistent=true | Misfire Policies | Plattformrichtlinie |
| Überlappung | Startet eine weitere Kopie | Pro Unit serialisiert | allow / forbid / replace | Plattformrichtlinie |
| Wiederholungsversuche | Keine | Neustartregeln des Dienstes | Konfigurierbar | Eingebaut |
| Sichtbarkeit von Fehlern | Lokale Mail, ungelesen | journald | Statusobjekte der Jobs | Status + Logs im Dashboard |
| Server am Leben zu halten | Ja – und er ist der SPOF | Ja | Der Cluster | Nein |
Zeitpläne überwachen
Das geplante Scheitern ist das leiseste Scheitern der Informatik: Ein Job, der nie gefeuert hat, gibt nichts von sich – keine Exception, keine Logzeile, keine E-Mail –, weil nichts gelaufen ist. Das Muster, das es behebt, dreht den Alarm um: Heartbeat-Monitoring – der Job pingt bei erfolgreichem Abschluss eine URL an, der Monitor erwartet den Ping innerhalb einer Karenzzeit, und das Ausbleiben löst den Alarm aus. Kombinieren Sie das mit der schlichten Hygiene, die klassisches cron nie hatte: Laufzeiten über die Zeit verfolgen (der Bericht, der letzten Monat 4 Minuten brauchte und heute Nacht 40, sagt Ihnen etwas), Ausgaben in echte Logs schreiben statt in lokale Mail, und die Zeitplan-Inventur dokumentieren – denn eine über fünf Server verstreute Crontab ist der Weg, auf dem Organisationen Jobs entdecken, von denen sie vergessen hatten, dass sie sie ausführen.
Typische Anwendungsfälle
- Berichte und Zusammenfassungen – die nächtliche Verdichtung, die die Code-Tabs skizzieren: aggregieren, schreiben, benachrichtigen.
- Bereinigung und Ablauf – TTL-Durchläufe, Entfernen von Waisen, Ablaufpässe für Sessions und Token.
- Datensynchronisation – periodisches Abholen aus Fremdsystemen, die keine Webhooks anbieten.
- Erinnerungen und Reaktivierung – zeitgesteuerte Sendungen: Testphasenende, abgebrochene Warenkörbe, Verlängerungshinweise.
- Prüfung und Abgleich – das geplante Audit, das auffängt, was ereignisgesteuerte Pfade verpasst haben.
Welchen Scheduler sollten Sie verwenden? Entscheidungsmatrix
| Situation | Greifen Sie zu |
|---|---|
| Eine Linux-Maschine, die Sie ohnehin betreiben | Klassisches cron – mit Sperren und einem Heartbeat |
| Laptop-artige oder nur zeitweise laufende Maschinen | anacron / systemd-Timer mit Persistenz |
| Ein Cluster, den Sie ohnehin betreiben | Dessen nativer Controller für geplante Jobs |
| App-Backend auf einem BaaS | Geplante Cloud Jobs – kein Server, Logs inklusive |
| Intervalle unter einer Minute oder krumme Intervalle | Ein echter Scheduler oder eine Queue, keine Crontab-Arithmetik |
| Ereignisförmige Arbeit, fälschlich als geplant etikettiert | Die Job-Queue – cron speist sie nur |
Grenzen und Trade-offs
- Zeitauslöser beschreiben wann, nicht ob. Ein Zeitplan feuert unabhängig davon, ob Arbeit da ist; ereignisgesteuerte Trigger und Queues passen zu Arbeit, die unregelmäßig eintrifft.
- “Ungefähr einmal” ist der ehrliche Vertrag. Selbst verwaltete Scheduler feuern gelegentlich doppelt oder überspringen einen Lauf; Idempotenz ist überall die Verantwortung des Jobs.
- Die Zeitzone ist eine Richtlinienentscheidung. Zeitpläne in UTC überstehen die Sommerzeit; Zeitpläne in Ortszeit dienen Menschen – wählen Sie bewusst und dokumentieren Sie laut.
- Die Frequenz hat eine Untergrenze und einen Preis. Minutengenau bei klassischem cron, plattformabhängige Untergrenzen anderswo; hochfrequentes Polling per cron ist meist eine Queue im Kostüm einer Uhr.
- Zeitpläne häufen sich im Stillen an. Jeder “vorübergehende” nächtliche Job ist dauerhaft, bis er inventarisiert wird; das Dashboard, das sie alle auflistet, ist ein unterschätztes Feature.
Geplanter Cloud Code mit Back4app
Back4app ist eine Open-Source-Plattform für Backend as a Service (BaaS), die eine verwaltete Datenbank, automatisch generierte REST- und GraphQL-APIs, Authentifizierung, Dateispeicher und Serverless-Funktionen mit Cloud Code kombiniert. Die Planung macht hier die moderne Spalte der Vergleichstabelle konkret: Definieren Sie Parse.Cloud.job in Cloud Code – der nächtliche Bericht der Code-Tabs, idempotent über seinen Datumsschlüssel, mit Master-Key-Zugriff für die nutzerübergreifende Aggregation – und planen Sie ihn dann im Panel “Background Jobs” des Dashboards: Jobname, Startzeit, Wiederholung, keine Crontab-Syntax und kein Server, auf dem diese Crontab läge. Läufe, Status und Fehler landen in den Serverlogs und im Jobs-Panel – die Spalte “Sichtbarkeit von Fehlern” standardmäßig beantwortet – und die Disziplinen, mit denen dieser Artikel schließt, bleiben bewusst Ihre: Schlüsseln Sie Jobs auf ihre Periode, halten Sie sie idempotent, und lassen Sie einen Heartbeat bestätigen, dass die Uhr der Plattform und Ihre Logik sich heute Nacht einig waren, wie jede Nacht.
Häufige Fragen
Was ist ein Cron-Job?
Eine Aufgabe, die zu festen Zeiten oder in festen Abständen automatisch ausgeführt wird – klassisch vom Cron-Daemon auf Unix-Systemen, der eine Crontab liest, und im weiteren Sinne jeder zeitgesteuerte Job auf jeder Plattform. Der Name stammt von chronos, griechisch für Zeit.
Was bedeuten die fünf Felder eines Cron-Ausdrucks?
Minute (0–59), Stunde (0–23), Tag des Monats (1–31), Monat (1–12), Wochentag (0–7, wobei 0 und 7 beide für Sonntag stehen), gefolgt vom Befehl. Der Stern steht für jeden Wert; Kommas zählen auf, Bindestriche bilden Bereiche, Schrägstriche definieren Schrittweiten.
Was passiert, wenn die Maschine zum geplanten Zeitpunkt ausgeschaltet ist?
Klassisches cron überspringt den Lauf einfach – es gibt kein Nachholen. Genau dafür gibt es anacron für Maschinen, die nur zeitweise laufen, bieten systemd-Timer eine Persistenzoption, und machen moderne Scheduler die Nachholrichtlinie zu einer ausdrücklichen Einstellung statt zu einer Überraschung.
Wie geht cron mit der Sommerzeit um?
Standardmäßig schlecht: Laut dem Handbuch selbst laufen Jobs, die in der "fehlenden Stunde" der Zeitumstellung liegen, nie, und Zeiten, die bei der Rückstellung doppelt vorkommen, laufen zweimal. Der stehende Rat: in UTC planen und kritische Jobs aus dem lokalen Fenster 00:00–03:00 heraushalten.
Was passiert, wenn ein Job noch läuft, während der nächste Lauf startet?
Klassisches cron startet munter eine zweite Kopie – und eine dritte. Überlappung braucht eine ausdrückliche Antwort: eine Lock-Datei, die den verspäteten Lauf überspringen lässt, oder die formalisierten Richtlinien moderner Scheduler – erlauben, verbieten oder die laufende Instanz ersetzen.
Woran erkenne ich, dass ein Cron-Job fehlgeschlagen ist?
Standardmäßig gar nicht – die Ausgabe landet in lokaler Mail, die niemand liest, und ein Zeitplan, der nie feuert, erzeugt überhaupt keinen Fehler, weil nichts gelaufen ist. Das Muster, das es behebt: Heartbeat-Monitoring – der Job pingt bei Erfolg eine URL an, und das Ausbleiben des Pings löst den Alarm aus.
Kann cron einen Job häufiger als einmal pro Minute ausführen?
Nein – eine Minute ist die Untergrenze von klassischem cron; der Daemon wacht auf, prüft die Tabelle und feuert im Minutentakt. Sekundengenauigkeit braucht einen anderen Scheduler: Ausdrücke mit sechs Feldern im Quartz-Stil, eine Schleife in einem Dienst oder eine Ereignis-Queue statt einer Uhr.
Brauche ich einen Server, um Cron-Jobs auszuführen?
Nicht mehr. Serverless-Plattformen hängen einen Zeitplan direkt an eine Funktion: Die Plattform besitzt die Uhr, feuert den Job, schreibt Logs und Status mit und wiederholt ihn gemäß Richtlinie – ein Zeitplan als Konfiguration statt als Datei auf einer Maschine, die Sie am Leben halten müssen.