Tools mentioned in this article
Open the browser-based tool while you read and try the workflow immediately.
Una sola línea como 0 3 * * 1-5 expresa “ejecutar a las 3:00 AM los días laborables”: ese es el poder de una expresión Cron. Desde el crontab de Linux hasta GitHub Actions, Kubernetes CronJob y la mayoría de los programadores en la nube, el mundo de la ejecución programada funciona con esta sintaxis.

Este artículo desglosa los cinco campos y los caracteres especiales de Cron, emparejando cada expresión con su significado real. Al final encontrarás las trampas más comunes y una sección de preguntas frecuentes.
La estructura básica: cinco campos
Una expresión crontab estándar consta de cinco campos separados por espacios.
┌───────────── minuto (0 - 59)
│ ┌───────────── hora (0 - 23)
│ │ ┌───────────── día del mes (1 - 31)
│ │ │ ┌───────────── mes (1 - 12)
│ │ │ │ ┌───────────── día de la semana (0 - 7, 0 y 7 = domingo)
│ │ │ │ │
* * * * *
El rango válido de cada campo es el siguiente.
| Campo | Rango | Notas |
|---|---|---|
| Minuto | 0–59 | |
| Hora | 0–23 | 0 = medianoche, 23 = 11 PM |
| Día del mes | 1–31 | |
| Mes | 1–12 | JAN–DEC también válidos (según implementación) |
| Día de la semana | 0–7 | 0 y 7 = domingo, 1 = lunes; SUN–SAT también válidos |
Nota: GitHub Actions y Kubernetes usan este formato de 5 campos. Quartz y AWS EventBridge añaden campos de “segundos” y/o “año” (6–7 campos), que requieren caracteres especiales como
?yLdescritos más abajo.
Entender los caracteres especiales con ejemplos
La expresividad de Cron proviene de los caracteres especiales permitidos en cada campo.
| Símbolo | Significado | Ejemplo | Se lee como |
|---|---|---|---|
* | todos los valores | * * * * * | cada minuto |
, | lista de valores | 0 9,12,18 * * * | a diario a las 9, 12 y 18 |
- | rango | 0 9-17 * * * | a diario, en punto de 9 a 17 |
/ | intervalo (paso) | */15 * * * * | cada 15 minutos |
? | sin valor concreto (día/semana) | 0 0 ? * MON | cada lunes a las 0:00 |
L | último (last) | 0 0 L * * | último día del mes a las 0:00 |
W | día laborable más cercano | 0 0 15W * * | el laborable más cercano al 15 |
# | enésimo día de la semana | 0 9 ? * MON#1 | primer lunes a las 9:00 |
Ten en cuenta que ?, L, W y # son extensiones de programadores tipo Quartz (Spring, Jenkins, EventBridge) y no están disponibles en el crontab estándar.
Cómo leer el / (paso)
*/15 significa “empieza en 0, avanza de 15 en 15”, es decir 0,15,30,45. Combinado con un rango, puedes fijar el punto de inicio.
*/15 * * * * → minutos 0,15,30,45 (cada 15 minutos)
5/10 * * * * → minutos 5,15,25,35,45,55 (cada 10 min desde el 5)
0 9-17/2 * * * → horas 9,11,13,15,17 (cada 2 horas, de 9 a 17)
Ejemplos de programación habituales
Patrones para copiar y pegar que aparecen a menudo en la práctica.
| Lo que quieres | Expresión Cron |
|---|---|
| Cada minuto | * * * * * |
| Cada 5 minutos | */5 * * * * |
| Cada hora (en punto) | 0 * * * * |
| A diario a medianoche | 0 0 * * * |
| A diario a las 9:30 | 30 9 * * * |
| Laborables a las 3 AM | 0 3 * * 1-5 |
| Cada 30 min, 9–18 en laborables | */30 9-18 * * 1-5 |
| Cada lunes a las 9 AM | 0 9 * * 1 |
| Día 1 del mes a las 0:00 | 0 0 1 * * |
| Último día del mes (Quartz) | 0 0 L * * |
| Primer lunes a las 9 AM (Quartz) | 0 9 ? * MON#1 |
Trampas habituales
1. Especificar día del mes y día de la semana es una condición OR
0 0 1 * 1 significa “medianoche del día 1 O del lunes”, no “cuando el día 1 sea lunes”. Es contraintuitivo, así que especifica solo uno y deja el otro como * (o ? en Quartz).
2. La zona horaria depende del entorno de ejecución
Muchos demonios cron usan la zona horaria del servidor, mientras que los contenedores y CI suelen ejecutarse en UTC. 0 0 * * * puede dispararse a medianoche UTC en lugar de tu medianoche local. Si quieres las 2 AM en JST (UTC+9), la expresión UTC es 0 17 * * *.
3. Dejar el campo de minutos como * lo ejecuta cada minuto
* 3 * * * (con la intención de “una vez a las 3 AM”) en realidad se ejecuta 60 veces durante la hora de las 3 AM. Para “una vez, a las 3:00 en punto”, usa 0 3 * * *.
4. Ejecuciones solapadas con intervalos cortos
Si un trabajo programado cada 5 minutos tarda más de 5 minutos, la siguiente ejecución empieza antes de que termine la anterior y se solapan. Deja margen en el intervalo o añade un mecanismo de bloqueo.
Elimina la “ansiedad antes de guardar” con una herramienta
Las expresiones Cron requieren práctica para leerse y escribirse, y las trampas anteriores son difíciles de detectar a simple vista. El analizador de expresiones Cron traduce tu expresión a lenguaje claro y simula las próximas ejecuciones, para que verifiques la programación de un vistazo antes de desplegar.
Preguntas frecuentes
¿El domingo es 0 o 7 en una expresión Cron?
La mayoría de las implementaciones aceptan tanto 0 como 7 para el domingo. El lunes es 1 y el sábado es 6. Para evitar confusiones, usa los nombres de tres letras (SUN, MON, …) donde estén soportados.
¿Cómo expreso “el último día del mes”?
En entornos que soportan L (Quartz, EventBridge), usa 0 0 L * *. El crontab estándar no tiene L, así que necesitas un rodeo: ejecutar en días candidatos de fin de mes (28–31) y comprobar la fecha en tu script, o calcularla por programa.
¿Cómo manejo la diferencia entre UTC y hora local?
Resta tu desfase UTC al campo de la hora. Para JST (UTC+9), las 2 AM JST pasan a ser las 5 PM UTC del día anterior, es decir 0 17 * * *. Si tu programador admite una zona horaria explícita, esa es la opción más fiable.
¿*/5 y 0/5 son lo mismo?
En el campo de los minutos son prácticamente idénticos (“cada 5 minutos”: 0,5,10,…). */5 significa “todo el rango, avanzando de 5 en 5”, mientras que 0/5 significa “desde 0, avanzando de 5 en 5”. La forma con inicio explícito ayuda cuando quieres desplazar el comienzo (p. ej. 7/15).