Skip to content
Volver al blog
Tutoriales

Cheat Sheet de Crontab: 50+ expresiones cron y guía de planificadores

Cheat sheet de crontab con 50+ expresiones cron listas para copiar, sintaxis explicada campo por campo, la trampa OR, zonas horarias y comparativa Kubernetes/GitHub/AWS.

13 min de lectura

Cheat Sheet de Crontab: 50+ expresiones cron, sintaxis y guía de planificadores modernos

Una expresión cron son cinco campos (minuto, hora, día del mes, mes, día de la semana) seguidos de un comando. Esa gramática mueve la planificación en Unix desde 1979 y hoy también mueve los CronJobs de Kubernetes, GitHub Actions, AWS EventBridge y los disparadores cron de Vercel. Se aprende una vez y se reutiliza en cualquier parte.

Esta página está pensada para quienes necesitan una expresión ahora mismo: una tarea de Linux, un CronJob de Kubernetes, un disparador de GitHub Actions, o averiguar por qué un job de cinco minutos solo se dispara cada hora. Salta a la Tabla de Referencia Rápida para copiar expresiones, a Sintaxis al Detalle para las reglas de cada campo, o abre el Generador Crontab — una alternativa privacy-first a crontab guru que corre en tu navegador — para validarlas en vivo.

Tabla de referencia rápida de expresiones cron

Treinta expresiones que cubren ~90% de las necesidades reales de programación. Cada una es cron POSIX de cinco campos válido: pégalas en crontab -e, en un schedule: de Kubernetes o en un cron: de GitHub Actions.

ProgramaciónExpresión cronEn palabras
Cada minuto* * * * *cada minuto, todo el día, todos los días
Cada 5 minutos*/5 * * * *minuto 0, 5, 10, …, 55
Cada 15 minutos*/15 * * * *minuto 0, 15, 30, 45
Cada 30 minutos*/30 * * * *minuto 0 y 30
Cada hora0 * * * *en punto de cada hora
Cada 2 horas0 */2 * * *hora 0, 2, 4, …, 22
Cada 6 horas0 */6 * * *hora 0, 6, 12, 18
Dos veces al día (9 AM + 9 PM)0 9,21 * * *minuto 0 de las horas 9 y 21
Cada día laborable a las 9 AM0 9 * * 1-5lun-vie 09:00
Cada fin de semana a las 9 AM0 9 * * 0,6sáb y dom 09:00
Diario a medianoche0 0 * * *todos los días 00:00
Diario a las 2:30 AM30 2 * * *ventana de batch con poco tráfico
Cada lunes a las 9 AM0 9 * * 1lunes 09:00
Cada viernes a las 5 PM0 17 * * 5viernes 17:00
Cada domingo a medianoche0 0 * * 0equivalente a @weekly
Día 1 del mes a medianoche0 0 1 * *día 1 a las 00:00 — equivalente a @monthly
Día 15 de cada mes al mediodía0 12 15 * *ventana de mitad de mes para nómina
Comprobación del último día (wrapper)0 0 28-31 * * + scriptrequiere una comprobación de fecha
Trimestral (1° de ene/abr/jul/oct)0 0 1 JAN,APR,JUL,OCT *primer día de cada trimestre
Anual (1 de enero)0 0 1 1 * o @yearlymedianoche de año nuevo
Cada 5 min, días laborables 9-5*/5 9-17 * * 1-5sondeo en horario laboral
Cada 30 min en fines de semana*/30 * * * 0,6monitoreo sáb/dom
Dos veces por hora, 15 y 4515,45 * * * *desfase respecto a la avalancha del :00
Primer lunes (wrapper)0 9 1-7 * 1 + chequeo ANDhace falta wrapper (ver abajo)
Macros@hourly @daily @weekly @monthly @yearlyno estándar pero ampliamente soportadas
Solo al reiniciar@rebootno estándar, solo vixie cron

Pega cualquiera en el Generador Crontab para previsualizar las próximas cinco ejecuciones antes de desplegar.

Sintaxis de cron al detalle: los 5 campos

Una expresión cron son cinco campos separados por espacios más un comando. Cada campo controla una porción de la programación. Es la misma sintaxis en todos los planificadores que aparecen en esta guía.

┌──────────── minuto       (0 - 59)
│ ┌────────── hora         (0 - 23)
│ │ ┌──────── día del mes  (1 - 31)
│ │ │ ┌────── mes          (1 - 12 o JAN-DEC)
│ │ │ │ ┌──── día de semana (0 - 6 o SUN-SAT; 0 y 7 significan domingo)
│ │ │ │ │
* * * * *  comando-a-ejecutar

Regla mnemotécnica: “Mi Hermano Diego Madruga Siempre” — Minuto, Hora, Día del mes, Mes, Semana (día de). De izquierda a derecha, de la unidad más pequeña a la más grande.

Valores permitidos campo por campo

CampoRangoAliasNotas
Minuto0-59ninguno0 significa “en punto”
Hora0-23ningunoreloj de 24 horas; 0 es medianoche, 12 es mediodía
Día del mes1-31ningunolos días inválidos para un mes simplemente nunca se disparan (31 de febrero)
Mes1-12JAN, FEB, MAR, …, DECno distingue mayúsculas y minúsculas
Día de la semana0-7SUN, MON, TUE, …, SATtanto 0 como 7 significan domingo

Operadores al detalle

Cinco operadores cubren cualquier expresión cron estándar:

OperadorSignificadoEjemploSe expande a
*cualquier valor* * * * *cada minuto
,lista0 9,12,17 * * *09:00, 12:00, 17:00
-rango inclusivo0 9-17 * * *cada hora de 09:00 a 17:00
/paso*/15 * * * *minuto 0, 15, 30, 45
mixtocombinado0 9-12,14-17 * * *mañana + tarde, sin la hora del almuerzo

El operador de paso merece atención. */N se ancla al valor más bajo del campo, no al instante actual. */15 significa “minuto 0, 15, 30, 45 de cada hora”, no “cada 15 minutos desde ahora”. Si guardas a las 12:03, la próxima ejecución es a las 12:15. Con una base que no sea comodín, 5/15 se lee “empieza en 5, luego cada 15”: minuto 5, 20, 35, 50.

Meses y días de la semana con nombre

Escribe meses y días de la semana como nombres, sin distinguir mayúsculas:

0 0 1 JAN,APR,JUL,OCT *    # primer día de cada trimestre
0 9 * * MON-FRI            # laborables a las 9 AM
0 17 * * FRI               # viernes a las 5 PM

Los nombres se leen mejor en revisiones de código; las formas numéricas son ligeramente más portables. Elige un estilo por proyecto.

Macros no estándar: @reboot, @daily y compañía

La mayoría de las implementaciones de cron aceptan seis macros de atajo:

MacroSe expande aSignificado
@yearly / @annually0 0 1 1 *una vez al año, 1 de enero a medianoche
@monthly0 0 1 * *día 1 de cada mes a medianoche
@weekly0 0 * * 0cada domingo a medianoche
@daily / @midnight0 0 * * *cada día a medianoche
@hourly0 * * * *en punto de cada hora
@reboot(especial)una sola vez al arrancar el daemon de cron

Estas macros no son estándar: vixie cron y cronie las soportan, pero los CronJob de Kubernetes, GitHub Actions y AWS EventBridge no. Para expresiones portables, escribe la forma de cinco campos. @reboot rara vez funciona en contenedores donde el daemon de cron puede no ser el proceso init.

50+ expresiones cron listas para copiar (agrupadas por caso de uso)

La Tabla de Referencia Rápida cubre los casos comunes. Esta sección añade seis grupos con ejemplos más densos.

Cada N minutos

* * * * *          # cada minuto
*/2 * * * *        # cada 2 minutos
*/5 * * * *        # cada 5 minutos — el caso clásico de "cada 5 minutos"
*/10 * * * *       # cada 10 minutos
*/15 * * * *       # cada 15 minutos
*/30 * * * *       # cada 30 minutos
0,30 * * * *       # minutos 0 y 30 explícitos (igual que */30)
*/45 * * * *       # OJO: solo se dispara en 0 y 45, luego se reinicia

*/45 es una trampa habitual: el minuto va de 0 a 59, así que cae en 0 y 45 y luego salta al inicio de la siguiente hora. Para una verdadera cadencia de 45 minutos necesitas un worker externo.

Variantes por hora

0 * * * *          # cada hora en el :00
30 * * * *         # cada hora en el :30
0 */2 * * *        # cada 2 horas, hora par
0 */6 * * *        # cada 6 horas
0 */12 * * *       # dos veces al día, 00:00 y 12:00
15 */2 * * *       # cada 2 horas, desfase de 15 min (evita el pico del :00)

Diarios a horas específicas

0 0 * * *          # medianoche (= @daily / @midnight)
30 2 * * *         # 02:30 — ventana de batch con poco tráfico
0 9 * * *          # 09:00
45 23 * * *        # 23:45 — cierres de fin de día
0 9,12,17 * * *    # tres veces al día
0 9-17 * * *       # cada hora de 09:00 a 17:00

Programaciones semanales

0 9 * * 1-5        # laborables a las 9 AM
0 9 * * 0,6        # fines de semana a las 9 AM
0 18 * * 5         # viernes a las 6 PM
0 0 * * 0          # domingo a medianoche (= @weekly)
0 9 * * MON,WED,FRI # lun/mié/vie a las 9 AM
*/30 9-17 * * 1-5  # cada 30 min, horario laboral, días laborables

Mensuales y trimestrales

0 0 1 * *          # día 1 del mes a medianoche (= @monthly)
0 0 15 * *         # día 15 — ventana de nómina
0 0 1,15 * *       # día 1 y 15 — quincenal
0 0 1 */3 *        # trimestral: primero de ene, abr, jul, oct
0 0 1 JAN,APR,JUL,OCT *  # lo mismo, con meses nombrados
0 0 28-31 * *      # los últimos días — combina con un wrapper que valide la fecha

El último día del mes no tiene expresión nativa en POSIX. Ejecuta un wrapper que compruebe date -d tomorrow +%d = 01, o usa un planificador con soporte nativo (Quartz tiene L; Kubernetes no).

Anuales y atajos con macros

0 0 1 1 *          # 1 de enero a medianoche (= @yearly / @annually)
0 0 25 12 *        # Navidad a medianoche
@yearly            # = 0 0 1 1 *
@monthly           # = 0 0 1 * *
@weekly            # = 0 0 * * 0
@daily             # = 0 0 * * *
@hourly            # = 0 * * * *
@reboot            # especial: una vez al iniciar el daemon (solo vixie cron)

Pega cualquiera de estas expresiones en el Generador Crontab para previsualizar las próximas cinco ejecuciones antes de desplegar.

Cron vs timers de systemd vs planificadores en la nube: matriz de decisión

Cron es la opción por defecto, no siempre la mejor. Comparativa de los siete planificadores más comunes, útil para decidir entre cron y systemd timer, Kubernetes CronJob frente a cron job de Vercel, o para migrar de crontab a una nube gestionada.

Característicavixie crontimer de systemdK8s CronJobGHA scheduleAWS EventBridgeVercel CronCloudflare Workers
Sintaxis de camposPOSIX 5 camposspec OnCalendarPOSIX 5 campos + timeZonePOSIX 5 camposQuartz 6 campos con ?POSIX 5 camposPOSIX 5 campos
Intervalo mínimo1 minuto1 segundo1 minutobest-effort, ≥15 min recomendado1 minuto1 minuto (plan Pro)1 minuto
Zona horaria explícitaCRON_TZ=Persistent=truespec.timeZone (1.27+)solo UTCScheduleExpressionTimezonesolo UTCsolo UTC
Recuperación de ejecuciones perdidasno (usa anacron)sí (Persistent=true)sí (startingDeadlineSeconds)nonono
Reintentos / backoffnoparcialsí (backoffLimit)reintento al fallarno
Control de concurrenciano (usa flock)parcialsí (concurrencyPolicy)nononono
Soporte de @rebootsí (vía OnBootSec=)nonononono

Timers de systemd: cuándo preferirlos sobre cron

En Linux basado en systemd, los timers son una alternativa seria: sintaxis de calendario legible, integración con el journal y recuperación de ejecuciones perdidas. Un timer y su servicio correspondiente:

# daily-report.timer
[Unit]
Description=Run daily report at 9 AM
[Timer]
OnCalendar=*-*-* 09:00:00
Persistent=true
Unit=daily-report.service
[Install]
WantedBy=timers.target
# daily-report.service
[Unit]
Description=Daily report job
[Service]
Type=oneshot
ExecStart=/usr/local/bin/daily-report.sh
User=reporter

Actívalo con systemctl enable --now daily-report.timer. La pieza diferenciadora es Persistent=true: si la máquina estaba apagada a las 9 AM, el timer se dispara en cuanto arranca; vixie cron no tiene equivalente sin anacron. Para reforzar la seguridad del servicio, mira nuestras mejores prácticas de seguridad.

Kubernetes CronJob

Kubernetes envuelve la programación POSIX con primitivas para concurrencia, historial y zona horaria explícita:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-report
spec:
  schedule: "0 2 * * *"
  timeZone: "America/New_York"     # Kubernetes 1.27+
  concurrencyPolicy: Forbid        # nunca correr dos a la vez
  startingDeadlineSeconds: 300     # saltar si se retrasa más de 5 min
  jobTemplate:
    spec:
      backoffLimit: 2
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: reporter
              image: reporter:1.4.0
              command: ["/usr/local/bin/report.sh"]

concurrencyPolicy: Forbid es tu equivalente a flock. Sin él, un job de larga duración se apila sobre su sucesor. Mira la sección de referencia de campos para todas las perillas.

Particularidades de GitHub Actions schedule

GitHub Actions acepta cron POSIX estándar de cinco campos:

on:
  schedule:
    - cron: '0 9 * * 1-5'   # laborables a las 9 AM UTC

Best-effort: bajo alta carga en los runners de GitHub, los jobs pueden dispararse minutos tarde o saltarse por completo. Evita intervalos menores a quince minutos. No hay ajuste de zona horaria: siempre UTC.

AWS EventBridge: cron estilo Quartz de seis campos

AWS EventBridge usa un cron al estilo Quartz con seis campos y un ? obligatorio en uno de los dos campos de día:

cron(0 9 * * ? *)

Orden de los campos: Minutos Horas Día-del-mes Mes Día-de-la-semana Año. Uno de los dos campos de día debe ser ? cuando el otro está restringido (es la forma de Quartz de resolver la ambigüedad OR de POSIX). Una copia directa desde un crontab de Linux no pasa la validación.

Vercel Cron, Cloudflare Workers, Render Cron Jobs

Las plataformas serverless más nuevas se estandarizan en POSIX de cinco campos. Un cron job de Vercel vive en vercel.json como { "crons": [{ "path": "/api/cron/nightly", "schedule": "0 2 * * *" }] }. Los Cron Triggers de Cloudflare Workers usan wrangler.toml:

[triggers]
crons = ["*/15 * * * *", "0 9 * * 1-5"]

Render usa render.yaml. Las tres corren en UTC sin override de zona horaria por programación, así que conviene diseñar en UTC desde el inicio.

7 trampas al depurar cron (y cómo detectarlas)

La mayoría de los reportes de “mi cron job no corre” tienen una de siete causas raíz. Revisa esta lista antes de culpar al planificador.

Trampa 1: el PATH es mínimo

Cron arranca los jobs con un $PATH mínimo, típicamente /usr/bin:/bin. Tu shell interactiva tiene /usr/local/bin, ~/.cargo/bin y una docena de entradas de .bashrc. Ninguna existe dentro de cron. Es la causa más frecuente al depurar el entorno PATH de cron.

Síntoma: node: command not found. Solución: define PATH al inicio del crontab, o usa rutas absolutas.

SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin

*/15 * * * *  /usr/local/bin/poll-api.sh
0 9 * * *     /home/deploy/.cargo/bin/my-rust-cli

Trampa 2: stdout y stderr se pierden en silencio

Por defecto, la salida de cron va a un buzón de correo que nadie lee. El job falla en silencio. Redirige ambos flujos:

*/15 * * * *  /usr/local/bin/job.sh >> /var/log/job.log 2>&1

Para salida JSON, encadena con jq; para extraer líneas de log, mira nuestro cheat sheet de regex. Para timers de systemd, journalctl -u tu-timer.service captura la salida.

Trampa 3: desfase de zona horaria entre dev y producción

Escribiste 0 9 * * * en tu laptop en Nueva York esperando que se dispare a las 9 AM hora del Este. El servidor corre en UTC. El cron se dispara a las 9 AM UTC: las 4 AM hora del Este, antes de que nadie lo note. Solución: pon los servidores en UTC y escribe las programaciones en UTC, o fija la zona horaria explícitamente.

CRON_TZ=America/New_York
0 9 * * *  /usr/local/bin/morning-report.sh

CRON_TZ funciona en vixie cron 3.0+; Kubernetes 1.27+ tiene spec.timeZone; AWS EventBridge tiene ScheduleExpressionTimezone; GitHub Actions siempre es UTC. Para UTC, horario de verano y matemáticas con epoch, mira nuestra guía del timestamp Unix.

Trampa 4: % sin escapar en los comandos

Cron interpreta los % sin escapar como saltos de línea: el resto de la línea se alimenta al comando como stdin. Por eso date +"%Y-%m-%d" se rompe. Escapa cada % como \%, o mueve la lógica a un script:

0 0 * * *  echo "Run at $(date +"\%Y-\%m-\%d")" >> /tmp/log

Trampa 5: ejecuciones solapadas

Un job */5 * * * * que de vez en cuando tarda siete minutos arrancará la siguiente instancia antes de que termine la anterior. Dos copias pelean por la misma fila, el mismo archivo de lock y la misma cuota de API. Serialízalo con flock:

*/5 * * * *  flock -n /tmp/job.lock /usr/local/bin/job.sh

-n sale inmediatamente si el lock está tomado. Para Kubernetes, define concurrencyPolicy: Forbid. Los permisos del archivo de lock importan: mira las mejores prácticas de seguridad.

Trampa 6: @reboot en contenedores

@reboot corre una vez cuando arranca el daemon de cron. En una VM eso coincide con el boot. En un contenedor el daemon de cron normalmente no es PID 1 y puede no estar corriendo siquiera. No uses @reboot en contenedores: pon la lógica de “ejecutar una vez al arrancar” en tu entrypoint o en un init container.

Trampa 7: la semántica OR de día del mes / día de la semana en POSIX

La trampa de cron más cara. Regla POSIX: cuando tanto día del mes como día de la semana están restringidos (ninguno es *), la programación se dispara cuando cualquiera de los dos coincide.

0 0 1 * 5 parece “medianoche del día 1, solo los viernes”, pero se dispara el día 1 Y todos los viernes: entre seis y diez disparos extra al mes.

# MAL: parece "día 1 del mes, solo si es viernes"
0 0 1 * 5
# BIEN: elige una sola restricción
0 0 1 * *          # cada día 1 del mes
0 0 * * 5          # cada viernes
# La semántica AND requiere un wrapper
0 0 1-7 * 5  [ "$(date +\%u)" = "5" ] && /script    # solo el primer viernes

Pega las expresiones sospechosas en el Generador Crontab; la previsualización de la próxima ejecución hace visible la trampa OR.

Planificadores modernos: cuándo NO usar cron

Cron es adecuado para “ejecuta este comando aproximadamente a esta hora, con una cadencia fija”. No es adecuado para varios problemas vecinos:

  • Flujos de trabajo con dependencias (correr A, luego B si A tuvo éxito) → Airflow, Prefect, Dagster.
  • Reintentos, backoff exponencial, colas de mensajes muertosTemporal, AWS Step Functions, Sidekiq.
  • Intervalos menores a un minuto → un worker de larga duración que duerme entre iteraciones.
  • Precisión al segundo → un daemon dedicado; los planificadores gestionados no garantizan tiempos exactos.
  • Trabajo dirigido por eventos → webhooks, colas de mensajes, streams de change-data-capture.

Cron no desaparece: Airflow, Step Functions y Sidekiq aceptan expresiones cron como entrada de sus flujos de trabajo. La gramática de cinco campos se reutiliza.

Referencia de campos de Kubernetes CronJob

La matriz de decisión más arriba mostraba un CronJob mínimo. Esta tabla cubre todos los campos relevantes de la sintaxis de cronjob en Kubernetes:

CampoPredeterminadoQué hace
scheduleobligatorioexpresión cron POSIX de 5 campos
timeZoneTZ del controladorzona horaria explícita (1.27+); usa nombres IANA
concurrencyPolicyAllowForbid salta nuevas ejecuciones mientras la anterior siga activa; Replace la cancela
startingDeadlineSecondssin límitesalta si el retraso supera este valor
successfulJobsHistoryLimit3número de Jobs exitosos a conservar
failedJobsHistoryLimit1número de Jobs fallidos a conservar
suspendfalsepausa sin borrar
backoffLimit6reintentos del Pod antes de marcar el Job como Failed
activeDeadlineSecondssin definirtope duro al tiempo de ejecución del Pod
ttlSecondsAfterFinishedsin definirauto-eliminación del Job tras estos segundos

Dos errores comunes: olvidar timeZone hace que la programación siga la zona horaria del host del kube-controller-manager (impredecible en Kubernetes gestionado); en una programación de un minuto, el valor por defecto successfulJobsHistoryLimit: 3 acumula tres objetos Job por minuto a menos que definas ttlSecondsAfterFinished.

Equivalentes de cron entre plataformas

macOS launchd. Apple recomienda launchd sobre cron. Un job de launchd es un .plist en ~/Library/LaunchAgents/:

<plist version="1.0"><dict>
  <key>Label</key><string>com.example.daily</string>
  <key>ProgramArguments</key><array><string>/usr/local/bin/daily.sh</string></array>
  <key>StartCalendarInterval</key>
  <dict><key>Hour</key><integer>9</integer><key>Minute</key><integer>0</integer></dict>
</dict></plist>

Cárgalo con launchctl load ~/Library/LaunchAgents/com.example.daily.plist. A diferencia de cron, launchd recupera las ejecuciones perdidas tras sleep/wake.

Programador de Tareas de Windows usa schtasks:

schtasks /create /tn "DailyReport" /tr "C:\scripts\report.bat" /sc DAILY /st 09:00
schtasks /create /tn "EveryFifteen" /tr "C:\scripts\poll.bat" /sc MINUTE /mo 15

En WSL, el cron nativo de Linux funciona pero se detiene cuando termina la sesión: usa el Programador de Tareas para lanzar jobs WSL siempre activos.

Cron en contenedores Docker. La mayoría de las imágenes slim (alpine, debian-slim, distroless) no incluyen daemon de cron. Instala cronie o busybox-cron y córrelo como PID 1 con tini o s6-overlay, o, casi siempre preferible, usa un CronJob de Kubernetes.

Consejos y patrones avanzados

Último día del mes

Cron no tiene operador nativo de “último día”. Ejecuta cada día en la ventana 28-31 y comprueba si mañana es día 1:

0 23 28-31 * *  [ "$(date -d tomorrow +\%d)" = "01" ] && /usr/local/bin/eom.sh

Enésimo día de la semana del mes

“Primer lunes” usa el mismo patrón de wrapper: restringe a los días 1-7 y luego comprueba el día de la semana:

0 9 1-7 * *  [ "$(date +\%u)" = "1" ] && /usr/local/bin/first-monday.sh

Para “último viernes”, usa los días 25-31 más la comprobación del día de la semana.

Desfase aleatorio para repartir carga

Cuando muchas máquinas corren el mismo cron, 0 0 * * * produce una estampida a medianoche UTC. Reparte con un retraso aleatorio:

RANDOM_DELAY=10                                              # cronie / anacron, en minutos
0 0 * * *  /usr/local/bin/job.sh

0 0 * * *  sleep $((RANDOM \% 600)); /usr/local/bin/job.sh   # portable

Monitoreo con heartbeat

Cron falla en silencio. El patrón de “interruptor del hombre muerto”: el job hace ping a un servicio de monitoreo tras cada ejecución exitosa; el servicio alerta cuando un ping esperado no llega. Healthchecks.io, Cronitor y Dead Man’s Snitch ofrecen planes gratuitos.

*/15 * * * *  /usr/local/bin/job.sh && curl -fsS --retry 3 https://hc-ping.com/your-uuid

Para lógica de monitoreo que ramifica según códigos de respuesta (200 saludable, 429 rate-limited, 503 degradado), mira nuestro cheat sheet de códigos de estado HTTP.

Diseña jobs idempotentes

Cron no tiene reintentos ni recuperación de ejecuciones perdidas ni control de concurrencia. La forma más fiable de compensarlo es hacer que el propio job sea seguro de ejecutar varias veces. En lugar de “envía el reporte de hoy a las 9 AM”, diséñalo como “envía el reporte de hoy si todavía no se envió”; las ejecuciones perdidas, los duplicados y los reintentos manuales convergen al mismo estado.

FAQ

¿*/5 * * * * realmente significa cada 5 minutos?

Casi — */5 * * * * está anclado al minuto 0, no a “cada 5 minutos desde ahora”. Se dispara en el minuto 0, 5, 10, …, 55 de cada hora. El paso */N es relativo al valor más bajo del campo, no al instante actual. Si guardas a las 12:03, la próxima ejecución es a las 12:05, no a las 12:08.

¿Qué significa 0 0 * * * en cron?

0 0 * * * significa todos los días a medianoche (00:00) en la zona horaria local del servidor. Campos: minuto 0, hora 0, cualquier día del mes, cualquier mes, cualquier día de la semana. Equivale a las macros @daily o @midnight. Para fijar la zona horaria, añade CRON_TZ=America/New_York al inicio del crontab.

¿Cómo ejecuto un cron job cada 30 segundos?

No puedes con cron POSIX estándar: la granularidad mínima es un minuto. Tres soluciones: dos jobs escalonados con * * * * * y sleep 30 && en uno; un timer de systemd con OnCalendar=*:*:0/30; o un worker de larga duración que duerma entre iteraciones. Lo último suele ser lo correcto.

¿Qué zona horaria usa cron por defecto?

La zona horaria local del sistema del servidor (/etc/timezone o la variable de entorno TZ). Un cron a las 9 AM en un servidor UTC se dispara a las 4 AM en la costa Este de EE. UU. Solución: define CRON_TZ= al inicio del crontab, o pon los servidores en UTC y diseña las programaciones en UTC. GitHub Actions siempre es UTC; Kubernetes 1.27+ soporta spec.timeZone.

¿Por qué mi cron job no se ejecuta?

Si tu cron job no se ejecuta, verifica en este orden: ¿está corriendo el daemon de cron (systemctl status cron); está definido $PATH en el crontab; está capturándose stderr (>> log 2>&1); está cargado el crontab del usuario (crontab -l); se escapó el % en los comandos; es la zona horaria la que esperas? La mayoría de los reportes de “no corre” son el segundo o el tercer punto.

¿La sintaxis de Kubernetes CronJob es igual a la de Linux cron?

Sí en el campo de programación: ambos usan cron POSIX de cinco campos. Kubernetes añade spec.timeZone (1.27+), concurrencyPolicy para controlar solapamientos, startingDeadlineSeconds para recuperar ejecuciones perdidas, y suspend: true para pausar. Linux cron no tiene nada de esto: tendrás que recurrir a flock y anacron.

¿Cuál es la diferencia entre @reboot y @daily?

@daily es una macro para 0 0 * * *: cada día a medianoche, con una programación fija. @reboot se ejecuta una vez cuando arranca el daemon de cron, sin programación recurrente. @reboot está soportado por vixie cron y cronie, pero no por Kubernetes CronJob, GitHub Actions ni AWS EventBridge. En contenedores, @reboot rara vez se dispara.

¿Cuál es la diferencia entre cron y crontab?

cron es el demonio en segundo plano que ejecuta tareas programadas; crontab es el archivo que las lista (y el comando crontab para editarlo). El demonio lee el crontab de cada usuario en un ciclo y ejecuta los comandos cuyo momento de ejecución coincide con la expresión cron. En resumen, cron es el motor y crontab es la receta.

Artículos relacionados

Ver todos los artículos