Skip to content

Agendamento cron

Cron a cada minuto

Para rodar um cron a cada minuto, use * * * * *. Um asterisco nos cinco campos casa com todos os minutos de todas as horas de todos os dias, o que dá 1.440 execuções por dia.

A cada minuto
Expressão* * * * *
Execuções1.440 vezes por dia
OnCalendar do systemd*:*:00

Como funciona

Um minuto é a menor resolução do cron clássico. O daemon acorda uma vez por minuto, compara o horário atual com cada linha e dispara as tarefas que batem. Com cinco asteriscos toda comparação dá certo, então a tarefa começa no segundo 0 de cada minuto, na prática um instante depois, dependendo de quão ocupado o daemon está.

Não existe macro para esse agendamento: o @hourly é o mais frequente. */1 * * * * e 0-59 * * * * significam o mesmo que * * * * *, e ninguém escreve assim.

Antes de fechar em “a cada minuto”, veja se a tarefa está só verificando se há trabalho. São 1.440 processos por dia, cada um relendo configuração e abrindo conexões, o que muitas vezes custa mais que um worker contínuo ou um consumidor de fila que reage na hora.

Explicação campo a campo
CampoValorSignificado
Minuto*todo minuto
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

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
* * * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1

# Same, but skip a run while the previous one is still going:
* * * * * 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_Paulo numa linha acima muda o fuso das linhas seguintes.

GitHub Actions

.github/workflows/scheduled.yml
on:
  schedule:
    - cron: '*/5 * * * *'  # GitHub’s minimum
  workflow_dispatch: {}
  • O GitHub Actions não roda um agendamento a cada minuto: a documentação define 5 minutos como intervalo mínimo, então */5 * * * * é o mais perto possível, e mesmo isso pode atrasar em horários de pico.

CronJob do Kubernetes

cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: scheduled-job
spec:
  schedule: "* * * * *"
  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": "* * * * *" }
  ]
}
  • 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 = ["* * * * *"]
  • 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 * * * * *', 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 minute

[Timer]
OnCalendar=*:*: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 '*:*: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 * * * * *", zone = "UTC")
public void runJob() {
    // ...
}

// Quartz CronTrigger:
CronScheduleBuilder.cronSchedule("0 * * * * ?")
  • 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

Execuções sobrepostas

Se uma execução pode passar de 60 segundos, a próxima começa com ela ainda rodando; o cron não verifica. Coloque flock -n /tmp/job.lock antes do comando para a segunda cópia sair na hora em vez de se acumular.

Agendadores hospedados podem não descer tanto

O mínimo do GitHub Actions é 5 minutos, e o plano Hobby da Vercel permite uma execução por dia. Um daemon cron de verdade, Kubernetes, Cloudflare Workers, Vercel Pro ou um agendador dentro da aplicação disparam a cada minuto.

E-mail e log demais

O cron manda por e-mail qualquer saída da tarefa para o dono do crontab (ou para o MAILTO). Com 1.440 execuções por dia a caixa lota. Redirecione stdout e stderr para um arquivo de log, ou para /dev/null se realmente não precisa deles.

Perguntas frequentes

* * * * * é o mesmo que */1 * * * *?
Sim. Um passo de 1 sobre a faixa inteira seleciona todos os valores, então os dois casam com todo minuto. * * * * * é a forma usual.
O cron a cada minuto começa exatamente no segundo 0?
Ele fica devido no segundo 0, mas o cron só garante o minuto. O daemon verifica uma vez por minuto e dispara as tarefas uma após a outra, então começar um ou dois segundos depois é normal.
O GitHub Actions roda um workflow a cada minuto?
Não. A documentação do GitHub define 5 minutos como o menor intervalo para workflows agendados, e as execuções ainda podem atrasar quando a plataforma está carregada.
Como rodar a cada minuto só em horário comercial?
Restrinja os campos de hora e dia da semana: * 9-17 * * 1-5 roda a cada minuto das 09:00 às 17:59, de segunda a sexta.

Revisado em por Arielton Oberek.