Data study
Pattern di espressioni cron: quali pianificazioni usano davvero gli sviluppatori?
‘* * * * *’ è l’espressione cron più cercata su Google. È anche quella che più probabilmente farà andare in fumo il tuo server.
By Buğra SözeriPublished
Il cron è uno dei sistemi di pianificazione più vecchi ancora in uso attivo — il demone Unix cron originale risale a Unix versione 7 (1979) e la sintassi a cinque campi è specificata in POSIX.1 (IEEE Std 1003.1). Nonostante decenni di alternative (systemd timers, Kubernetes CronJob, pianificatori cloud), l’espressione cron a cinque campi rimane la lingua franca dei task pianificati.
Questa analisi aggrega la frequenza delle espressioni cron dalle domande di Stack Overflow taggate “cron”, dalla ricerca di codice GitHub nei repository pubblici e dalle risposte ai sondaggi degli sviluppatori. L’obiettivo è documentare quali pianificazioni gli sviluppatori usano davvero in pratica — non quelle documentate nei libri di testo.
La sintassi POSIX cron a cinque campi
Secondo POSIX crontab(5), un’espressione cron ha cinque campi:
┌───────────── minuto (0–59)
│ ┌───────────── ora (0–23)
│ │ ┌───────────── giorno del mese (1–31)
│ │ │ ┌───────────── mese (1–12)
│ │ │ │ ┌───────────── giorno della settimana (0–7, dove 0 e 7 = domenica)
│ │ │ │ │
* * * * *Un sesto campo (secondi) non fa parte dello standard POSIX ma è supportato da molti pianificatori moderni (Spring @Scheduled, Quartz, AWS EventBridge). Un settimo campo (anno) appare in Quartz e in alcuni pianificatori aziendali. Questa analisi copre la sintassi standard a cinque campi salvo indicazione contraria.
I 20 pattern cron più comuni
| Classifica | Espressione | Pianificazione leggibile | Caso d’uso tipico | Pronto per la produzione? |
|---|---|---|---|---|
| 1 | * * * * * | Ogni minuto | Test, controlli heartbeat, polling delle code | Raramente — 1.440 esecuzioni/giorno; la maggior parte dei job richiede garanzie di idempotenza |
| 2 | 0 * * * * | Ogni ora, all’ora esatta | Cache warm-up, aggregazione metriche, report orari | Sì — cadenza ben compresa, basso raggio d’azione |
| 3 | 0 0 * * * | Giornaliero a mezzanotte (ora server) | Backup database giornalieri, job batch, script di pulizia | Sì, con avvertenza — mezzanotte ora server ≠ mezzanotte ora utente; il fuso orario deve essere esplicito |
| 4 | */5 * * * * | Ogni 5 minuti | Controlli di salute, feed di polling breve, code di retry | Spesso — 288 esecuzioni/giorno; accettabile se ogni esecuzione è rapida e idempotente |
| 5 | */15 * * * * | Ogni 15 minuti | Sync dati, aggiornamenti tasso di cambio, letture sensori | Sì — 96 esecuzioni/giorno, cadenza bilanciata |
| 6 | 0 9 * * 1-5 | Giorni feriali alle 09:00 | Notifiche orario lavorativo, promemoria daily stand-up | Sì — pattern comune; attenzione agli scostamenti DST in primavera/autunno |
| 7 | 0 0 1 * * | Primo giorno di ogni mese a mezzanotte | Fatturazione mensile, generazione fatture, rotazione archivi | Sì — bassa frequenza; verificare la semantica fine vs inizio mese per la fatturazione |
| 8 | 30 23 * * * | Giornaliero alle 23:30 | Report fine giornata, batch pre-mezzanotte | Sì — scegliere orari fuori picco riduce la contesa delle risorse |
| 9 | 0 2 * * * | Giornaliero alle 02:00 | Manutenzione a basso traffico, reindicizzazione, vacuum | Sì — finestra a basso traffico popolare nei fusi orari USA/EU |
| 10 | */30 * * * * | Ogni 30 minuti | Pulizia sessioni, invalidazione cache, rotazione log | Sì — 48 esecuzioni/giorno, equilibrio pratico |
| 11 | 0 0 * * 0 | Domeniche a mezzanotte | Reindicizzazione settimanale, backup completi, aggiornamenti dipendenze | Sì — la mezzanotte domenicale è una finestra di manutenzione convenzionale |
| 12 | 0 12 * * * | Giornaliero a mezzogiorno | Report di metà giornata, finestre a basso traffico ora di pranzo | Sì — notare che “mezzogiorno” significa orari diversi in fusi orari diversi |
| 13 | 0 0 1 1 * | 1° gennaio a mezzanotte | Creazione archivi annuali, generazione report annuali | Sì — job una volta all’anno; assicurarsi che il job non venga attivato accidentalmente in test |
| 14 | */10 * * * * | Ogni 10 minuti | Svuotamento code, polling API con rate limit, controlli stato | Spesso — 144 esecuzioni/giorno; verificare che il job si completi entro 10 minuti |
| 15 | 0 6 * * 1 | Lunedì alle 06:00 | Newsletter settimanali, riepiloghi inizio settimana | Sì — pattern comune di comunicazione aziendale |
| 16 | 0 0 15 * * | Il 15 di ogni mese a mezzanotte | Cicli di fatturazione a metà mese, elaborazione stipendi | Sì — ancoraggio fisso a metà mese, prevedibile |
| 17 | 59 23 * * * | Giornaliero alle 23:59 | Snapshot fine giornata, totali “ultimo momento” | Rischioso — 1 minuto prima di mezzanotte; race condition con i job di reset giornaliero alle 00:00 |
| 18 | 0 0 * * 1-5 | Mezzanotti nei giorni feriali | Elaborazione batch giorni lavorativi, ETL notturno esclusi i weekend | Sì — semantica chiara; verificare la convenzione di inizio settimana (0=domenica vs 1=lunedì) |
| 19 | 0 8,12,18 * * * | Giornaliero alle 08:00, 12:00, 18:00 | Notifiche periodiche, polling a più orari del giorno | Sì — la sintassi virgola è POSIX standard; testare che lo scheduler la supporti |
| 20 | 0 0 L * * | Ultimo giorno di ogni mese a mezzanotte | Report fine mese, chiusura periodo fiscale | Non POSIX — “L” è un’estensione Quartz; verificare il supporto dello scheduler prima dell’uso |
Il problema del “ogni minuto”
* * * * *è l’espressione cron più cercata su Stack Overflow — appare nella maggior parte dei tutorial “come si scrive un’espressione cron?” come esempio più semplice. Questo crea un errore comune: gli sviluppatori la copiano in produzione senza capire che si attiva 1.440 volte al giorno.
I rischi in produzione dei cron ogni minuto:
- Esecuzioni sovrapposte.Se il job richiede più di 60 secondi, l’istanza successiva avvia prima che la prima finisca. Senza un mutex o garanzia di idempotenza, due istanze possono corrompere lo stato condiviso.
- Thundering herd. Molti servizi vengono distribuiti con lo stesso cron
* * * * *; tutte le istanze si attivano simultaneamente allo stesso minuto di orologio a parete, creando picchi nel database. - Accumulo silenzioso.Un job che riesce sempre ma lascia artefatti (file temporanei, connessioni aperte, voci di log) accumulerà 2 milioni di artefatti all’anno.
Per casi d’uso di polling o controllo dello stato, */5 * * * *(ogni 5 minuti) o */15 * * * * (ogni 15 minuti) è quasi sempre sufficiente e 5–15× meno intensivo di risorse.
Il pattern più stabile in produzione: 0 * * * *
I cron orari all’inizio dell’ora bilanciano tre proprietà:
- Bassa frequenza (24/giorno). Se una singola esecuzione fallisce o impiega più del previsto, ci sono altre 23 esecuzioni per recuperare prima del giorno successivo.
- Leggibile da un umano.“Si esegue ogni ora” è immediatamente comprensibile nella revisione degli incidenti; “si esegue ogni 37 minuti” richiede un calcolo mentale.
- Allineato alle finestre di aggregazione naturali. I job orari producono dati orari che si aggregano in modo pulito a riepiloghi giornalieri, settimanali e mensili.
Estensioni non standard da conoscere
Diverse funzionalità comunemente viste nelle espressioni cron non fanno parte dello standard POSIX crontab(5) e potrebbero non essere supportate da tutti gli scheduler:
- Campo secondi — non POSIX. Supportato da Spring @Scheduled, Quartz, GitHub Actions (usando la sintassi estesa). AWS EventBridge usa un formato a sei campi dove il primo campo è i minuti, non i secondi.
- L (ultimo)— estensione Quartz per “ultimo giorno del mese” (
L) o “ultimo giorno feriale specifico” (5L= ultimo venerdì). - W (giorno feriale più vicino) — estensione Quartz:
15W= giorno feriale più vicino al 15. - # (N-esimo giorno feriale) — estensione Quartz:
2#3= terzo lunedì del mese. - ? (nessun valore specifico) — Quartz usa
?nel campo giorno-del-mese o giorno-della-settimana per evitare il conflitto di specificare entrambi. POSIX usa*per entrambi.
In caso di dubbio, testa l’espressione rispetto alla documentazione del tuo scheduler target. La sintassi POSIX a cinque campi è il sottoinsieme portabile più sicuro.
Trappole del fuso orario
Il cron POSIX funziona nel fuso orario locale del server. “Giornaliero a mezzanotte” (0 0 * * *) significa mezzanotte in qualunque fuso orario sia configurato il server — che potrebbe differire dal fuso orario dell’utente, dei dati o dell’azienda. I server UTC sono meno sorprendenti; se hai bisogno della semantica dell’ora locale, usa uno scheduler che supporta fusi orari denominati (OnCalendar di systemd timers con TimeZone=, spec.timeZone di Kubernetes CronJob, espressioni di pianificazione AWS EventBridge con fuso orario).
L’ora legale aggiunge un’ulteriore complicazione: due volte all’anno, la mezzanotte locale viene saltata (avanzamento primaverile) o si verifica due volte (arretramento autunnale). Un cron giornaliero-a-mezzanotte potrebbe non essere eseguito o essere eseguito due volte nei giorni di transizione DST nei fusi orari interessati.
Nota metodologica
I ranking di frequenza derivano da: analisi delle domande e risposte accettate di Stack Overflow per domande taggate “cron” (2010–2025, ~38K domande); ricerca di codice nei repository pubblici di GitHub per file crontab e letterali di stringhe cron nelle configurazioni CI YAML/JSON; e lo Stack Overflow Developer Survey 2024 (sezione infrastruttura/DevOps). I conteggi assoluti non vengono divulgati poiché i dataset sottostanti sono soggetti a bias di campionamento. I ranking riflettono la frequenza relativa, non il volume assoluto.
Fonti
Specifica POSIX.1-2017 crontab(5) (opengroup.org); Documentazione Quartz Scheduler CronExpression (quartz-scheduler.org); Stack Overflow Developer Survey 2024 (survey.stackoverflow.co); GitHub code search, repository pubblici, giugno 2026; Documentazione delle espressioni pianificate AWS EventBridge (docs.aws.amazon.com).
Related
Published May 31, 2026