Skip to content

Agendamento cron

Cron a cada 6 horas

A expressão cron para rodar a cada 6 horas é 0 */6 * * *. Ela roda quatro vezes por dia, às 00:00, 06:00, 12:00 e 18:00.

A cada 6 horas
Expressão0 */6 * * *
Execuções4 vezes por dia
OnCalendar do systemd*-*-* 0/6:00:00

Como funciona

O */6 no campo de hora se expande para 0, 6, 12 e 18, e o minuto fixo 0 faz de cada uma delas uma única execução na hora cheia. É o mesmo que 0 0,6,12,18 * * *.

As execuções são ancoradas na meia-noite, não no momento do deploy. Para usar outros quatro horários, comece o passo em outro ponto: 0 3-23/6 * * * roda às 03:00, 09:00, 15:00 e 21:00. Ou simplesmente liste as horas que você quer.

Quatro vezes por dia é uma cadência típica para verificar certificados, fazer backup de bancos movimentados e reconstruir caches. Na Vercel exige plano Pro, já que o Hobby permite uma execução por dia.

Explicação campo a campo
CampoValorSignificado
Minuto0minuto 0 (hora cheia)
Hora*/6a cada 6 horas: 0, 6, 12, 18
Dia do mês*todo dia do mês
Mês*todo mês
Dia da semana*todo dia da semana

Próximas execuções

Relógio do agendador

Como no GitHub Actions sem timezone, na Vercel, na Cloudflare e no Kubernetes com timeZone "Etc/UTC".

Próximas execuções, calculadas no seu navegador a partir de agora
ExecuçãoSeu horárioUTC
1Calculando… 
2  
3  
4  
5  

Versões prontas para colar

O mesmo agendamento em cada agendador, com o que muda em cada um.

crontab (Linux, macOS, BSD)

crontab -e
# m h dom mon dow  command
0 */6 * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1
  • O cron usa o fuso horário do servidor. No cronie (Fedora, RHEL), CRON_TZ=America/Sao_Paulo numa linha acima muda o fuso das linhas seguintes.

GitHub Actions

.github/workflows/scheduled.yml
on:
  schedule:
    - cron: '0 */6 * * *'
  workflow_dispatch: {}
  • Roda em UTC, a menos que você defina timezone, e só no branch padrão. A documentação do GitHub avisa que execuções agendadas podem atrasar em horários de pico e que, em repositórios públicos, o agendamento é desativado após 60 dias sem atividade.
  • O início de cada hora é o horário de maior fila no GitHub. Se o minuto exato não importa, troque o 0 por outro minuto, como 17, para atrasar menos.

CronJob do Kubernetes

cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: scheduled-job
spec:
  schedule: "0 */6 * * *"
  timeZone: "Etc/UTC"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: job
              image: busybox:1.36
              command: ["/bin/sh", "-c", "date; echo running"]
  • spec.timeZone é estável desde o Kubernetes 1.27; sem ele, vale o fuso do kube-controller-manager. concurrencyPolicy: Forbid pula uma execução se a anterior ainda estiver rodando.

Cron Jobs da Vercel

vercel.json
{
  "crons": [
    { "path": "/api/cron", "schedule": "0 */6 * * *" }
  ]
}
  • A Vercel sempre usa UTC, não aceita nomes como MON ou JAN e não deixa definir dia do mês e dia da semana ao mesmo tempo.
  • Roda mais de uma vez por dia, então precisa do plano Pro ou Enterprise. No Hobby, a documentação diz que o deploy falha com expressões que rodam mais de uma vez por dia.

Cloudflare Workers

wrangler.toml
[triggers]
crons = ["0 */6 * * *"]
  • Cron Triggers rodam em UTC. Mudanças podem levar até 15 minutos para se propagar pela rede da Cloudflare.

node-cron (Node.js)

scheduler.js
import cron from 'node-cron';

// 6 campos: o primeiro (segundos) é opcional
cron.schedule('0 0 */6 * * *', async () => {
  await runJob();
}, { timezone: 'UTC', noOverlap: true });
  • O agendamento vive dentro do processo Node: se ele cair, nada roda; se houver três réplicas, a tarefa roda três vezes. noOverlap pula um disparo enquanto o anterior não terminou.

Timer do systemd

job.timer + job.service
# /etc/systemd/system/job.timer
[Unit]
Description=Run job.service every 6 hours

[Timer]
OnCalendar=*-*-* 0/6:00:00

[Install]
WantedBy=timers.target

# /etc/systemd/system/job.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/job.sh

# systemctl daemon-reload && systemctl enable --now job.timer
  • Confira com systemd-analyze calendar '*-*-* 0/6:00:00', que mostra a forma normalizada e a próxima execução. AccuracySec padrão é 1min, então o disparo pode variar até um minuto.

Spring @Scheduled e Quartz

Java
@Scheduled(cron = "0 0 */6 * * *", zone = "UTC")
public void runJob() {
    // ...
}

// Quartz CronTrigger:
CronScheduleBuilder.cronSchedule("0 0 0/6 * * ?")
  • No Spring, o primeiro dos 6 campos são os segundos; o resto segue o cron comum (0 ou 7 = domingo).
  • No Quartz, um dos campos de dia precisa ser ?, por isso o dia da semana leva ?.

Armadilhas

Passos de hora que não dividem 24

0 */5 * * * roda às 0, 5, 10, 15 e 20 e depois 0 do dia seguinte: um intervalo de 4 horas de madrugada. 0 */7 * * * dá 0, 7, 14, 21 e um intervalo de 3 horas. Só 1, 2, 3, 4, 6, 8 e 12 dividem o dia por igual.

Quais 6 horas depende do fuso do relógio

Em UTC, 00:00/06:00/12:00/18:00 vira 21:00/03:00/09:00/15:00 no horário de Brasília. Se as execuções precisam fugir do horário comercial ou do pico de tráfego, escolha as horas no fuso que o agendador realmente usa.

0 6 * * * é uma vez por dia

Sem a barra, o 6 no campo de hora é só 06:00. O intervalo exige */6.

Perguntas frequentes

Qual é a expressão cron para a cada 6 horas?
0 */6 * * *, que roda às 00:00, 06:00, 12:00 e 18:00.
Como rodar a cada 6 horas começando às 3h?
0 3-23/6 * * * roda às 03:00, 09:00, 15:00 e 21:00. 0 3,9,15,21 * * * é a mesma coisa.
Como fica a cada 6 horas no systemd?
OnCalendar=*-*-* 0/6:00:00, que dispara às 00:00, 06:00, 12:00 e 18:00 no fuso do sistema.
Quantas vezes por dia 0 */6 * * * roda?
Quatro: 24 horas divididas por 6.

Revisado em por Arielton Oberek.