Agendamento cron
Cron a cada 5 minutos
A expressão cron para rodar a cada 5 minutos é */5 * * * *. Ela dispara nos minutos 0, 5, 10 e assim por diante até o 55 de toda hora, 288 vezes por dia.
| Expressão | */5 * * * * |
|---|---|
| Execuções | 288 vezes por dia |
| OnCalendar do systemd | *:0/5 |
Como funciona
O */5 no campo de minuto é um passo: começa no menor valor (0) e pega de cinco em cinco até o maior (59). Isso dá 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 e 55. Os outros quatro campos são *, então esses minutos valem em toda hora de todo dia.
O agendamento segue o relógio, não o momento em que você salvou o crontab. Salvou às 10:03, a primeira execução é às 10:05 e depois às 10:10. Como 5 divide 60 sem sobra, o intervalo é sempre de 5 minutos, inclusive na virada da hora.
É também o piso do GitHub Actions: a documentação define 5 minutos como o menor intervalo para workflows agendados. No GitHub, entenda como “mais ou menos a cada 5 minutos”, porque as execuções podem começar atrasadas quando a plataforma está cheia.
| Campo | Valor | Significado |
|---|---|---|
| Minuto | */5 | a cada 5 minutos: 0, 5, 10, …, 55 |
| Hora | * | toda hora |
| 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
Como no GitHub Actions sem timezone, na Vercel, na Cloudflare e no Kubernetes com timeZone "Etc/UTC".
| Execução | Seu horário | UTC |
|---|---|---|
| 1 | Calculando… | |
| 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)
# m h dom mon dow command
*/5 * * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1
# Same, but skip a run while the previous one is still going:
*/5 * * * * flock -n /tmp/job.lock /usr/local/bin/job.sh- O cron usa o fuso horário do servidor. No cronie (Fedora, RHEL),
CRON_TZ=America/Sao_Paulonuma linha acima muda o fuso das linhas seguintes.
GitHub Actions
on:
schedule:
- cron: '*/5 * * * *'
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.
CronJob do Kubernetes
apiVersion: batch/v1
kind: CronJob
metadata:
name: scheduled-job
spec:
schedule: "*/5 * * * *"
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: Forbidpula uma execução se a anterior ainda estiver rodando.
Cron Jobs da Vercel
{
"crons": [
{ "path": "/api/cron", "schedule": "*/5 * * * *" }
]
}- A Vercel sempre usa UTC, não aceita nomes como
MONouJANe 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
[triggers]
crons = ["*/5 * * * *"]- Cron Triggers rodam em UTC. Mudanças podem levar até 15 minutos para se propagar pela rede da Cloudflare.
node-cron (Node.js)
import cron from 'node-cron';
// 6 campos: o primeiro (segundos) é opcional
cron.schedule('0 */5 * * * *', 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.
noOverlappula um disparo enquanto o anterior não terminou.
Timer do systemd
# /etc/systemd/system/job.timer
[Unit]
Description=Run job.service every 5 minutes
[Timer]
OnCalendar=*:0/5
[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/5', que mostra a forma normalizada e a próxima execução.AccuracySecpadrão é 1min, então o disparo pode variar até um minuto.
Spring @Scheduled e Quartz
@Scheduled(cron = "0 */5 * * * *", zone = "UTC")
public void runJob() {
// ...
}
// Quartz CronTrigger:
CronScheduleBuilder.cronSchedule("0 0/5 * * * ?")- 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
Todo mundo roda em :00, :05, :10
*/5 é o agendamento mais comum que existe, então bancos e APIs compartilhados levam um pico em todo múltiplo de 5. Desloque o seu com um início diferente: 2-59/5 * * * * roda em 2, 7, 12, …, 57, continuando a cada 5 minutos.
É horário do relógio, não “5 minutos depois do fim da última”
Se a execução leva 4 minutos, a próxima começa 1 minuto depois do fim. Se leva 6, a próxima começa com ela ainda rodando. Use flock -n no crontab, concurrencyPolicy: Forbid no Kubernetes ou noOverlap no node-cron.
5 * * * * não é a cada 5 minutos
Sem a barra, o 5 no campo de minuto é um valor único: uma vez por hora, no minuto 5. A forma com passo é */5.
Perguntas frequentes
- O que significa */5 numa expressão cron?
- É um passo: de cinco em cinco dentro da faixa do campo, começando pelo menor valor. No campo de minuto dá 0, 5, 10, …, 55; no campo de hora, */5 seria 0, 5, 10, 15 e 20.
- Como rodar a cada 5 minutos começando no minuto 2?
- Use uma faixa com passo: 2-59/5 * * * * roda em 2, 7, 12, …, 57. GitHub Actions e a maioria das bibliotecas também aceitam 2/5, que o cronie rejeita.
- O GitHub Actions roda a cada 5 minutos?
- Sim, 5 minutos é o mínimo que o GitHub permite. Mas não há garantia de pontualidade: a documentação diz que workflows agendados podem atrasar com a plataforma carregada, principalmente no início de cada hora.
- Como rodar a cada 5 minutos só em dias úteis?
- Acrescente uma faixa no dia da semana: */5 * * * 1-5 roda a cada 5 minutos, o dia todo, de segunda a sexta.
Revisado em por Arielton Oberek.