Guide: Background Jobs and Scheduling
This guide moves a slow task (sending a welcome email) out of the request, runs it with a worker, and schedules a nightly cleanup.
1. Choose a queue driver
Section titled “1. Choose a queue driver”For development the default sync driver runs jobs immediately. To really use a queue, use the database driver:
QUEUE_CONNECTION=databasephp naluz migrate # creates the jobs and failed_jobs tables2. Write the job
Section titled “2. Write the job”php naluz make:job SendWelcomeEmailnamespace App\Jobs;
use App\Models\User;use Naluz\Mail\Mailer;use Naluz\Queue\Job;
final class SendWelcomeEmail extends Job{ protected int $tries = 5; protected int|array $backoff = [10, 60, 300];
public function __construct(public readonly int $userId) {} // public properties are the job data
public function handle(Mailer $mailer): void // dependencies are injected { $user = User::findOrFail($this->userId);
$message = $mailer->message()->to($user->email, $user->name)->subject('Welcome!')->text("Hi {$user->name}"); $mailer->send($message); }
public function failed(\Throwable $e): void { logger()->error('Welcome email failed for {id}', ['id' => $this->userId, 'exception' => $e]); }}Pass IDs and re-load the model inside handle() so the payload stays small and fresh.
3. Dispatch it
Section titled “3. Dispatch it”SendWelcomeEmail::dispatch($user->id);dispatch((new SendWelcomeEmail($user->id))->onQueue('mail')->delay(60));4. Run a worker
Section titled “4. Run a worker”php naluz queue:work --queue=default --sleep=3A worker finishes the current job on SIGTERM/SIGINT (when pcntl is installed). Run workers under a supervisor in production. See
Deployment.
Inspect and retry failures:
php naluz queue:failedphp naluz queue:retry all5. Schedule recurring work
Section titled “5. Schedule recurring work”return function (Schedule $schedule): void { $schedule->command('queue:work --stop-when-empty')->everyMinute()->withoutOverlapping(); $schedule->job(new App\Jobs\PruneOldRecords())->dailyAt('03:00');};Add one cron entry on the server:
* * * * * cd /path/to/app && php naluz schedule:run >> /dev/null 2>&1php naluz schedule:list # tasks and their next run6. Test it
Section titled “6. Test it”Use the sync driver in tests, or call the worker once:
SendWelcomeEmail::dispatch($user->id);// with queue.default=sync the job has already run; assert on ArrayTransport::$sentSecurity notes
Section titled “Security notes”- Payloads are encrypted with
APP_KEY; rotating the key withoutprevious_keyssends queued jobs tofailed_jobs. - Do not put secrets in job properties; pass IDs.