Scheduler
Agendamento de tarefas (cron).
Agendamento — Schedule
Agendamento de tarefas 100% nativo do illuminate/console Scheduling. Um único cron entry
no servidor (* * * * *) é suficiente — o Schedule controla os horários internamente, sem
precisar de uma entrada de cron por tarefa.
Como funciona
cron (a cada minuto)
└── php artisan schedule:run
└── carrega as tarefas definidas em routes/console.php
└── verifica quais estão no horário
├── sim → executa (com mutex se ->withoutOverlapping())
└── não → ignora
Definindo tarefas
Tarefas vivem em routes/console.php — sem app/Console/Kernel.php (estilo Laravel
11+): o arquivo é carregado automaticamente e usa o facade Schedule direto.
use Illuminate\Support\Facades\Schedule;
// Chamar uma closure
Schedule::call(function () {
SystemSession::where('expires_at', '<', now())->delete();
})->dailyAt('03:00')->name('limpar-sessoes')->withoutOverlapping();
// Rodar um comando artisan (inclusive os seus, registrados via make:command)
Schedule::command('relatorio:mensal')->monthlyOn(1, '06:00');
// Despachar um Job na fila
Schedule::call(fn () => RelatorioVendasJob::dispatch())
->weeklyOn(1, '07:00')
->name('relatorio-vendas');
// Executar um comando de shell
Schedule::exec('sh /home/user/scripts/backup.sh')
->dailyAt('02:30')
->name('backup-banco')
->appendOutputTo('/home/user/logs/backup.log');
O próprio framework já agenda 3 tarefas internas (drenagem do MadTrace e limpeza de exports
do grid) — veja o topo de routes/console.php. O MadBuilder injeta as tarefas do seu projeto
entre os marcadores >>> MADBUILDER:SCHEDULE / <<< MADBUILDER:SCHEDULE — não edite essa
faixa à mão.
Frequências disponíveis
Por minuto / hora
->everyMinute() // a cada 1 minuto
->everyTwoMinutes() // a cada 2 minutos
->everyFiveMinutes() // a cada 5 minutos
->everyTenMinutes() // a cada 10 minutos
->everyFifteenMinutes() // a cada 15 minutos
->everyThirtyMinutes() // a cada 30 minutos
->hourly() // toda hora no minuto 0
->hourlyAt(15) // toda hora no minuto 15
->everyTwoHours() // a cada 2 horas
->everySixHours() // a cada 6 horas
Por dia / semana / mês
->daily() // todo dia à meia-noite
->dailyAt('08:30') // todo dia às 08:30
->twiceDaily(6, 18) // duas vezes por dia: 06:00 e 18:00
->weekdays() // apenas dias úteis (seg-sex)
->weekends() // apenas fins de semana
->mondays() // apenas segundas (...tuesdays(), wednesdays() etc.)
->weekly() // toda segunda à meia-noite
->weeklyOn(3, '10:00') // toda quarta às 10:00
->monthly() // todo dia 1 do mês à meia-noite
->monthlyOn(15, '12:00') // todo dia 15 às 12:00
->quarterly() // primeiro dia de cada trimestre
->yearly() // 1 de janeiro à meia-noite
Cron expression customizada
->cron('0 9 * * 1-5') // 09:00 em dias úteis
->cron('*/10 8-18 * * *') // a cada 10min entre 8h e 18h
Modificadores de comportamento
// Evita sobreposição (mutex nativo do Laravel, via cache lock)
->withoutOverlapping()
->withoutOverlapping(10) // aguarda até 10min pelo lock antes de pular
// Roda em background — o scheduler não espera o processo terminar
->runInBackground()
// Restrições de horário
->between('8:00', '17:00')
->unlessBetween('23:00', '6:00')
// Condicional
->when(fn () => date('j') === '1') // só roda se a condição for true
->skip(fn () => app()->isDownForMaintenance()) // nunca roda se for true
// Output
->appendOutputTo('/caminho/log.log')
->emailOutputTo('time@empresa.com') // exige MAIL_MAILER configurado
CLI
# Ver todas as tarefas com próxima execução
php artisan schedule:list
# Executar tarefas devidas agora (o que o cron chama)
php artisan schedule:run
# Modo desenvolvimento — loop em foreground, substitui o cron localmente
php artisan schedule:work
# Rodar uma tarefa específica agora, fora do horário (debug)
php artisan schedule:test
Cron no servidor
A ÚNICA entrada necessária — o Laravel decide internamente o que está no horário:
Linux (crontab -e)
* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1
cPanel (shared hosting)
No painel Cron Jobs, adicionar:
* * * * * /usr/local/bin/php /home/SEU_USER/public_html/artisan schedule:run >> /home/SEU_USER/logs/scheduler.log 2>&1
Desenvolvimento local
# Substitui o cron localmente (loop em foreground)
php artisan schedule:work
Pausar tarefas sem editar código
Tarefas registradas em routes/console.php podem ser pausadas/reativadas em runtime, sem
deploy, via a tela Central de Comando → Agendamentos (admin). O mecanismo: uma linha em
mad_sys_schedule_override com active = 0 faz schedule:run/schedule:work pularem
aquela tarefa (->skip(...) injetado automaticamente em todo evento do Schedule, casando
pelo nome do comando artisan). Sem linha de override → tarefa roda normalmente
(fail-open: se a tabela não existir, nada é pausado). A conexão consultada é
config('mad.schedule.connection', 'iam').
A mesma tela mostra última execução e status de cada tarefa (lidos de
mad_sys_schedule_log), além de um botão "Executar agendador agora" para forçar um
schedule:run fora do cron — útil pra QA.
Veja também
- Filas (Queue) — para tarefas agendadas que disparam Jobs em background em vez de rodar inline no processo do scheduler.