Gerador e Leitor de Expressões Cron
*/15minute*hour*day of month*month*day of weekPróximas execuções
seu horário localNada do que você digita aqui é armazenado, registrado ou compartilhado.
Escreva uma expressão cron e veja os próximos horários em que ela vai realmente rodar. Cada campo é validado, e agendamentos que nunca podem disparar são sinalizados.
Como usar
- Digite uma expressão, ou escolha uma predefinição para começar.
- Os cinco campos são identificados abaixo para você ver qual é qual.
- Confira os próximos horários antes de colocar em produção.
Os cinco campos
Uma expressão cron padrão tem cinco campos separados por espaços: minuto 0-59, hora 0-23, dia do mês 1-31, mês 1-12 e dia da semana 0-7, em que tanto 0 quanto 7 significam domingo. Meses e dias da semana podem ser escritos com os nomes em inglês de três letras.
Cada campo aceita as mesmas quatro construções. O asterisco corresponde a todos os valores. Uma lista separada por vírgulas corresponde a qualquer um deles. Um intervalo com hífen corresponde a tudo entre os extremos. Um passo com barra pega cada enésimo valor de um intervalo, então */15 no campo de minuto é a cada quarto de hora e 0-30/10 são os minutos 0, 10, 20 e 30.
Os atalhos @hourly, @daily, @weekly, @monthly e @yearly se expandem para as expressões óbvias e valem a pena quando se encaixam, porque não há como lê-los errado.
A regra do dia do mês e do dia da semana
Este é o comportamento do cron que pega quase todo mundo, e ele está na especificação, não é acidente. Quando os campos de dia do mês e de dia da semana estão ambos restritos - nenhum é asterisco -, eles se combinam com OU, e não com E.
Então 0 0 1 * MON não significa o dia 1º quando cair numa segunda-feira. Significa todo dia 1º de cada mês e também toda segunda-feira. Se você quer só as segundas, o campo de dia do mês precisa ser asterisco. Se quer só o dia 1º, o campo de dia da semana precisa ser asterisco. Não existe forma padrão de expressar a interseção numa expressão de cinco campos, e a solução usual é agendar a união e verificar a data dentro do próprio job.
É exatamente esse caso que a lista de próximas execuções existe para flagrar. Ler os campos diz o que você escreveu; ler as datas diz o que vai acontecer.
Fusos horários e horário de verão
Os horários de execução mostrados aqui estão no fuso do seu navegador. O servidor que vai de fato rodar o job tem o próprio fuso, muitas vezes UTC, e a diferença entre os dois é uma fonte rotineira de jobs disparando na hora errada. Confira a configuração do servidor, ou o campo de fuso do seu agendador, antes de confiar num horário exato.
O horário de verão acrescenta um problema mais sério. Num fuso que o adota, um job agendado para 02:30 simplesmente não roda na madrugada em que o relógio é adiantado, porque esse horário não existe, e roda duas vezes na madrugada em que ele é atrasado. Para qualquer coisa em que uma execução perdida ou duplicada importe - cobrança, conciliação, envio de e-mails -, agende em UTC ou fora da janela de uma às três da manhã, quando as transições acontecem.
As implementações também divergem sobre o que fazer com jobs perdidos enquanto a máquina estava suspensa ou desligada. Algumas os ignoram, outras os executam ao acordar, e outras executam todas as ocorrências perdidas de uma vez.
Extensões que você vai encontrar por aí
Cinco campos é o padrão, e é o que o cron do Linux, o CronJob do Kubernetes e a maioria dos agendadores hospedados aceitam. Vários sistemas muito usados o estendem, e expressões copiadas entre eles nem sempre funcionam igual.
O Quartz, e com ele o agendador do Spring, usa seis ou sete campos, acrescentando segundos no início e um ano opcional no fim, então uma expressão de cinco campos colada ali é lida com tudo deslocado uma posição e roda na hora errada em vez de falhar. O Quartz também acrescenta L para último, W para dia útil mais próximo e # para o enésimo dia da semana do mês. O Vixie cron, padrão no Linux, acrescenta @reboot. O AWS EventBridge usa seis campos e exige que exatamente um dos dois campos de dia seja um ponto de interrogação em vez de asterisco.
Esta ferramenta valida e explica o padrão de cinco campos. Se o seu agendador é um dos citados, consulte a documentação dele antes de supor que a expressão significa a mesma coisa lá.
O ambiente em que um job de cron realmente roda
Mais jobs agendados falham por motivos de ambiente do que por motivos de agendamento. O cron não carrega o seu perfil de shell, então o PATH é mínimo - muitas vezes apenas /usr/bin e /bin - e um comando que funciona no seu terminal falha com command not found. O hábito confiável é usar caminhos absolutos para o interpretador e para o script, ou definir o PATH explicitamente no topo do crontab.
O diretório de trabalho é o home do usuário, e não o do projeto, então caminhos relativos vão parar em lugares inesperados. As variáveis de ambiente definidas pelo seu shell de login não existem ali, incluindo tudo o que vinha de um .env carregado por algum hook do shell. E o sinal de porcentagem tem significado especial no crontab: ele é convertido em quebra de linha, e é por isso que uma string de formato de data como %Y quebra um comando silenciosamente a menos que seja escapada.
A outra metade é a saída. Tudo o que um job escreve em stdout ou stderr é enviado por e-mail ao dono se houver um agente de transporte de e-mail, e descartado se não houver - é assim que jobs falham em silêncio por meses. Redirecione para um arquivo de log que você realmente leia, ou faça o job reportar ao seu sistema de monitoramento tanto no sucesso quanto na falha.
Sobreposição, idempotência e a execução que não aconteceu
O cron inicia um job no horário marcado independentemente de a execução anterior ter terminado. Um job de cinco minutos em um agendamento de cinco minutos acaba rodando duas cópias ao mesmo tempo, depois três, e a falha costuma aparecer como trabalho duplicado ou deadlock, não como erro de agendamento. Um lock - flock no Linux, um advisory lock no banco de dados ou um lease em um armazenamento compartilhado - é a correção padrão, e ele precisa de um timeout para que uma execução que travou não bloqueie todas as seguintes.
Projete cada job de modo que rodá-lo duas vezes seja inofensivo. Na prática, isso quase sempre significa registrar o que foi processado em vez de supor que o agendamento define isso: selecione as linhas ainda não tratadas, marque-as e deixe que uma segunda execução não encontre nada a fazer.
A imagem espelhada é a execução perdida. Se a máquina estava suspensa ou o processo falhou, algumas implementações pulam aquela ocorrência, outras a executam atrasada e outras ainda disparam todas as ocorrências perdidas de uma vez. O Anacron existe justamente para lidar com máquinas que não ficam ligadas o tempo todo, e os agendadores de contêineres têm as próprias políticas, que vale a pena ler antes de depender de uma delas.
Alternativas modernas ao crontab
Os timers do systemd substituem o cron na maioria das distribuições Linux atuais e oferecem coisas que o cron nunca teve: ordenação por dependência, limites de recursos, log automático no journal, atrasos aleatórios para evitar picos simultâneos e Persistent=true, para que uma execução perdida aconteça no próximo boot. O custo é mais configuração, já que um timer e uma unidade de serviço são dois arquivos em vez de uma linha.
O CronJob do Kubernetes adota a mesma sintaxe de cinco campos e acrescenta política de concorrência, limites de histórico e tratamento de prazo - exatamente o conjunto de problemas descrito acima, agora explícito. Agendadores gerenciados - barramentos de eventos na nuvem, agendamentos de CI, timers serverless - costumam prometer entrega ao menos uma vez em vez de exatamente uma vez, o que novamente joga a idempotência para o lado do job.
Para tarefas dentro de uma aplicação, uma fila com mensagem atrasada costuma servir melhor do que qualquer agendador, porque retentativas, visibilidade e monitoramento vêm junto com a fila em vez de serem acoplados depois.
Os agendamentos que as pessoas realmente escrevem
A cada quinze minutos é */15 * * * *. Toda noite às 02:30 é 30 2 * * *. Dias úteis às 09:00 é 0 9 * * 1-5. O primeiro dia de cada mês à meia-noite é 0 0 1 * *, e o último dia do mês não tem expressão padrão nenhuma - a solução habitual é rodar diariamente e sair a menos que amanhã seja dia primeiro.
Dois hábitos deixam um crontab legível no futuro. Espalhe a carga em vez de agendar tudo na hora cheia: 7 3 * * * não é mais difícil de escrever do que 0 3 * * * e evita disputar recursos com todos os outros jobs da máquina. E comente cada linha dizendo o que ela faz e quem é o responsável, porque um crontab sobrevive à memória de quem adicionou a entrada.
Quando um agendamento é realmente complexo, dividi-lo em duas entradas simples costuma ser mais claro do que uma única expressão engenhosa - e clareza é exatamente o que você quer às três da manhã, quando o job que rodou em silêncio por um ano de repente para.
Saber se o job chegou a rodar
A falha característica do trabalho agendado é o silêncio. Um job que falha de forma barulhenta é corrigido no mesmo dia; um job que simplesmente deixa de rodar não produz saída alguma, e ninguém percebe até o relatório semanal que ele gera faltar pela terceira semana seguida.
O padrão que resolve isso é o monitoramento por dead man's switch: o job envia um ping a um serviço de monitoramento quando termina com sucesso, e o serviço alerta quando o ping não chega dentro da janela esperada. Isso inverte a direção usual do alerta e pega tudo - um host que caiu, um crontab apagado, um deploy que falhou, uma máquina que nunca voltou de um reboot - porque, vistos de fora, todos esses casos são idênticos: nada acontecendo.
Registre o que uma execução fez, não apenas que ela aconteceu. Uma linha com o horário de início, o de término, a quantidade de registros processados e o status de saída transforma uma suspeita vaga em resposta, e é a diferença entre saber que um job rodou e saber que ele funcionou. Quando um job noturno processa zero linhas em silêncio por um mês, a contagem no log costuma ser a única evidência de quando isso começou.
Perguntas frequentes
- Por que mostrar os próximos horários em vez de só uma descrição?
- Porque uma expressão pode estar perfeitamente válida e ainda assim não significar o que você pretendia. Ler cinco campos diz o que você escreveu; ver as próximas seis datas diz o que vai acontecer. É nessa diferença que bugs de agendamento costumam ser pegos.
- O que acontece se eu definir dia do mês e dia da semana juntos?
- Eles são combinados com OU, não com E. Então "0 0 1 * MON" dispara no dia 1 de todo mês E em toda segunda-feira, não apenas nas segundas que caem no dia 1. Isso surpreende quase todo mundo, é comportamento especificado e não uma esquisitice, e os próximos horários deixam isso óbvio.
- Qual sintaxe cron é suportada?
- Cron padrão de cinco campos: minuto, hora, dia do mês, mês, dia da semana. Curingas, intervalos, listas, passos e nomes de mês e dia com três letras são todos aceitos, assim como os atalhos @daily, @hourly, @weekly, @monthly e @yearly. Domingo pode ser escrito como 0 ou 7.
- Em que fuso horário estão os horários mostrados?
- No fuso horário do seu navegador. O cron em um servidor roda no fuso daquele servidor, que muitas vezes é UTC e muitas vezes não é o que seu computador mostra, então confira a configuração do servidor antes de contar com uma hora exata.
- Por que ele diz que uma expressão nunca pode rodar?
- Algumas combinações são impossíveis, como o dia 30 de fevereiro. Em vez de mostrar uma lista vazia, a ferramenta diz isso diretamente.
Última atualização:
Inclua os passos, o resultado esperado e o resultado real. Remova segredos e dados pessoais.
