Diagnosticar cron no Magento é um saco. O sintoma é sempre vago — pedido não fatura, e-mail não sai, sitemap não atualiza — e a única fonte de verdade é uma tabela chamada cron_schedule que você abre no MySQL, com data em UTC e status em inglês.
Tem um módulo gratuito que resolve isso e é mantido de verdade: o EthanYehuda_CronjobManager. A versão v2.3.1 saiu em 21 de julho de 2026 e já roda em PHP 8.1 até 8.5.
Instale em dois comandos
Na raiz do Magento:
composer require ethanyehuda/magento2-cronjobmanager
php bin/magento setup:upgradeEm produção, o de sempre depois: setup:di:compile, setup:static-content:deploy e cache:flush. A tabela de compatibilidade que o autor mantém no README:
| Magento | Versão do módulo |
|---|---|
| 2.4.9 | ^2.0 |
| 2.4.6, 2.4.7 e 2.4.8 | ^1.15 ou ^2.0 |
| 2.4.4 e 2.4.5 | ^1.13.3 ou ^2.0 |
| 2.1.x e 2.0.x | não suportado |
Duas exigências do composer.json que valem conferir antes: a extensão ext-posix do PHP, que ele usa para checar processo vivo, e PHP dentro da faixa ~8.1.0 a ~8.5.0. Licença OSL-3.0, a mesma do Magento.
Um aviso honesto: o módulo declara colunas novas na tabela cron_schedule do core — group, hostname, duration, pid e kill_request. É via declarative schema, então some quando você remove o módulo, mas é bom saber que ele mexe em tabela do core antes de subir em produção.
O que aparece no admin
O menu entra em System > Tools > Cron Job Manager. São três telas que interessam:
- Manage. O grid da
cron_schedule: job code, status, agendado para, executado em, duração e a mensagem de erro completa. Dá para filtrar por status e achar em dois cliques aquele job que está emerrordesde terça. - Timeline. A fila desenhada numa linha do tempo, com escala dinâmica. Serve para enxergar sobreposição — três jobs pesados começando no mesmo minuto é um clássico de servidor que trava de hora em hora.
- Configuration. Lista os jobs registrados pelos módulos, com a expressão cron de cada um. Aqui dá para mudar a frequência, restaurar o padrão do sistema e desabilitar um job — é só apagar a expressão.
Esse último item é o que mais me salva. Módulo de terceiro com job quebrado enchendo o log de error? Apaga a expressão dele, o job para de ser agendado e a loja segue enquanto você resolve com o fornecedor. Sem editar crontab.xml de módulo que não é seu.
A permissão é separada, no recurso EthanYehuda_CronjobManager::cronjobmanager. Como a tela roda e mata processo, deixe liberada só para quem é técnico — o pessoal de loja não precisa disso.
O ajuste que resolve o job preso em running
Esse é o cenário mais comum de "cron travado": o processo PHP morreu no meio — OOM killer, deploy, restart do servidor — e a linha na cron_schedule ficou eternamente em running. Magento não agenda de novo um job que ele acha que ainda está rodando, e aquele job simplesmente nunca mais roda.
O módulo tem uma opção justamente para isso, em Stores > Configuration > Advanced > System > Cron Job Manager:
php bin/magento config:set system/cron_job_manager/clean_running_schedule 1
php bin/magento cache:clean configCom ela ligada, o módulo varre os jobs em running, confere pelo PID se o processo existe mesmo naquele host e, se não existe, marca como error com a mensagem Process went away. A fila destrava sozinha. Repare que ele compara o hostname antes de decidir: em ambiente com mais de um servidor rodando cron, ele não mata o que está rodando na outra máquina.
Já que está lá, ligue também o aviso por e-mail de job com erro:
php bin/magento config:set system/cron_job_manager/email_notification 1
php bin/magento config:set system/cron_job_manager/email_recipients "[email protected]" Pela linha de comando também
Ele instala três comandos no bin/magento:
php bin/magento cronmanager:showjobs
php bin/magento cronmanager:runjob sitemap_generate
php bin/magento cronmanager:killjob sitemap_generate -pO showjobs lista todos os job codes registrados na instalação — inclusive os dos módulos de terceiro, que é a informação que ninguém acha na documentação. O runjob executa um job pelo código, na hora, sem esperar o agendamento. Já o killjob tem um detalhe: sozinho, ele só registra um pedido de encerramento, que o próprio agendador do Magento processa depois. Com -p, ele manda o sinal direto para o processo que está rodando. Quando o job travou de vez, é o -p que resolve.
Só não confunda o módulo com solução para cron que não está instalado. Ele lê e manipula a fila; quem coloca job na fila e executa é o crontab do sistema operacional. Se o crontab -l do usuário do PHP está vazio, o grid vai aparecer vazio também, e aí o problema é outro.
Na minha rotina: instalo, ligo o clean_running_schedule, ligo o e-mail de erro e uso o grid como primeira tela de diagnóstico. Em loja com integração de ERP, quase todo chamado de "o pedido não foi para o sistema" morre nessa tela em dois minutos.
Perguntas rápidas
Dá para usar em produção sem risco?
Dá, e é onde ele serve. Os cuidados são dois: restringir a permissão a usuários técnicos, porque a tela executa e mata processo, e lembrar que ele adiciona colunas na tabela cron_schedule. Teste em homologação antes, como você faria com qualquer módulo.
Ele funciona com vários servidores rodando cron?
Funciona. A limpeza de jobs órfãos compara o hostname gravado na linha antes de conferir o PID, então ele não marca como erro um job que está rodando de verdade em outra máquina do cluster.
Preciso desse módulo se eu já uso a CLI?
Não precisa, mas ajuda. O ganho é ver duração e mensagem de erro por job num grid filtrável, em vez de montar consulta SQL toda vez. Quem opera a loja e não tem acesso ao banco é quem mais aproveita.
Pra conferir na fonte
- EthanYehuda_CronjobManager no GitHub — GitHub
- ethanyehuda/magento2-cronjobmanager — Packagist
- Configure and run cron — Adobe Experience League