Alle Artikel
Laravel4 min

Laravel Task Scheduling & Cronjob-Optimierung für Production

Laravel bietet mit seinem Task Scheduling System eine elegante Alternative zu traditionellen Cron-Einträgen. Statt dutzende Cronjobs direkt auf dem Server zu konfigurieren, definierst du alle wiederkehrenden Aufgaben zentral in deiner Laravel-Anwendung. In diesem Artikel zeige ich dir, wie du Laravel Task Scheduling Cronjob richtig aufsetzt, für Production optimierst und typische Fallstricke vermeidest.

Warum Laravel Task Scheduling nutzen?

Traditionelle Cronjobs erfordern Shell-Zugriff und manuelle Konfiguration auf jedem Server. Laravel Task Scheduling zentralisiert diese Logik in deinem Code:

  • Ein einziger Cron-Eintrag statt mehrerer
  • Versionskontrolle für deine Scheduling-Logik
  • Testbarkeit deiner geplanten Tasks
  • Flüssige API für komplexe Zeitpläne
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command('emails:send-newsletter')
             ->weekly()
             ->mondays()
             ->at('09:00')
             ->timezone('Europe/Berlin');
    
    $schedule->command('reports:generate')
             ->dailyAt('23:30')
             ->withoutOverlapping();
}

Setup: Der eine Cronjob

Für Laravel Task Scheduling Cronjob brauchst du genau einen Cron-Eintrag auf deinem Server:

* * * * * cd /pfad/zu/deiner/app && php artisan schedule:run >> /dev/null 2>&1

Dieser läuft jede Minute und prüft, welche Tasks fällig sind. Laravel selbst entscheidet intern, was wann ausgeführt wird.

Crontab bearbeiten

# Als Webserver-User (z.B. www-data)
sudo crontab -u www-data -e

# Eintrag hinzufügen
* * * * * cd /var/www/html/deine-app && php artisan schedule:run >> /dev/null 2>&1

Wichtig: Der Cron muss als User laufen, der Schreibrechte auf storage/ und bootstrap/cache/ hat.

Task Definition: Die wichtigsten Patterns

Command Scheduling

Am saubersten: Eigene Artisan Commands für Tasks erstellen.

// app/Console/Commands/CleanupOldRecords.php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class CleanupOldRecords extends Command
{
    protected $signature = 'cleanup:old-records {--days=30}';
    protected $description = 'Löscht Datensätze älter als X Tage';

    public function handle()
    {
        $days = $this->option('days');
        $deleted = DB::table('logs')
            ->where('created_at', '<', now()->subDays($days))
            ->delete();
        
        $this->info("$deleted Einträge gelöscht");
        return 0;
    }
}
// app/Console/Kernel.php
$schedule->command('cleanup:old-records --days=60')
         ->daily()
         ->at('02:00');

Closure-basierte Tasks

Für einfache Operationen:

$schedule->call(function () {
    Cache::put('last-schedule-run', now());
})->everyMinute();

Job Dispatching

Für umfangreiche Background-Prozesse:

$schedule->job(new ProcessReportData)
         ->dailyAt('01:00')
         ->onOneServer();

Production-Optimierung für Laravel Task Scheduling

1. Overlapping Prevention

Verhindere, dass ein Task startet, während die vorherige Instanz noch läuft:

$schedule->command('import:heavy-data')
         ->hourly()
         ->withoutOverlapping(10); // Timeout nach 10 Minuten

Laravel nutzt Cache als Lock-Mechanism. Stelle sicher, dass dein Cache Driver persistent ist (Redis/Database, nicht Array).

2. Single Server Execution

In Multi-Server-Setups (Load Balancer) muss ein Task nur einmal laufen:

$schedule->command('reports:send')
         ->daily()
         ->onOneServer();

Voraussetzung: Zentraler Cache (Redis) oder Database Cache-Driver, den alle Server teilen.

3. Maintenance Mode Handling

$schedule->command('emails:send')
         ->everyFiveMinutes()
         ->evenInMaintenanceMode();

Standardmäßig laufen Tasks nicht während php artisan down. Nur für kritische Tasks aktivieren.

4. Fehlerbehandlung & Monitoring

$schedule->command('api:sync')
         ->everyTenMinutes()
         ->before(function () {
             Log::info('API Sync startet');
         })
         ->after(function () {
             Log::info('API Sync abgeschlossen');
         })
         ->onFailure(function () {
             // Benachrichtigung senden
             Mail::to('admin@example.com')
                 ->send(new TaskFailedMail('api:sync'));
         })
         ->emailOutputOnFailure('dev@example.com');

5. Task Timeouts

Lange laufende Tasks sollten Timeouts haben:

$schedule->command('import:large-dataset')
         ->daily()
         ->withoutOverlapping()
         ->runInBackground() // Blockiert schedule:run nicht
         ->timeout(3600); // 1 Stunde

Output & Logging

Log in Datei schreiben

$schedule->command('backup:run')
         ->daily()
         ->appendOutputTo(storage_path('logs/backup.log'));

Nur bei Output benachrichtigen

$schedule->command('monitor:check')
         ->everyMinute()
         ->emailOutputTo('alerts@example.com');

Performance-Tipps für Laravel Task Scheduling Cronjob

Queue Tasks statt direkter Ausführung

Schwere Operationen sollten in Queues:

$schedule->call(function () {
    // Schnell: Job nur dispatchen
    ProcessMonthlyReports::dispatch();
})->monthly();

Der Scheduler dispatcht nur, der Queue Worker verarbeitet asynchron.

Schedule:work für Development

In Development-Umgebungen ist schedule:work praktischer als Cron:

php artisan schedule:work

Läuft im Vordergrund und führt Tasks kontinuierlich aus – ideal für lokales Testing.

Task-Frequency prüfen

php artisan schedule:list

Zeigt alle Tasks mit nächster Laufzeit. Perfekt zum Verifizieren deiner Konfiguration.

Monitoring & Debugging

Task History tracken

Nutze Packages wie spatie/laravel-schedule-monitor:

composer require spatie/laravel-schedule-monitor
php artisan schedule-monitor:list

Tracked:

  • Welche Tasks wann liefen
  • Fehlgeschlagene Executions
  • Vergessene/nie laufende Tasks

Health Checks mit Timestamps

Einfacher Ansatz ohne Package:

// In Kernel.php
$schedule->call(function () {
    Cache::put('scheduler-last-run', now());
})->everyMinute();

// In Health Check
public function checkScheduler()
{
    $lastRun = Cache::get('scheduler-last-run');
    
    if (!$lastRun || $lastRun->diffInMinutes(now()) > 5) {
        // Alert: Scheduler läuft nicht!
    }
}

Typische Probleme & Lösungen

Task läuft nicht

Checklist:

  1. Cron-Eintrag korrekt? crontab -l prüfen
  2. PHP-Pfad korrekt? which php im Cron verwenden
  3. App-Pfad absolut, nicht relativ
  4. User-Permissions auf storage/ korrekt?

"No scheduled commands are ready to run"

Normal! Laravel Task Scheduling Cronjob prüft jede Minute, aber führt nur aus, was fällig ist.

Tasks laufen mehrfach (Multi-Server)

onOneServer() verwenden und sicherstellen, dass alle Server denselben Cache nutzen:

// config/cache.php
'default' => env('CACHE_DRIVER', 'redis'),

Timezone-Handling

// In Kernel.php
protected function schedule(Schedule $schedule)
{
    // Global
    $schedule->useTimezone('Europe/Berlin');
    
    // Oder per Task
    $schedule->command('report:daily')
             ->dailyAt('08:00')
             ->timezone('America/New_York');
}

Fazit

Laravel Task Scheduling Cronjob ist ein mächtiges Tool für Production-Anwendungen. Mit einem einzigen Cron-Eintrag, sauberer Fehlerbehandlung und richtigen Performance-Optimierungen läuft dein Scheduling System zuverlässig und wartbar.

Die wichtigsten Takeaways:

  • Ein Cron-Eintrag für alle Tasks
  • withoutOverlapping() und onOneServer() für Production
  • Monitoring über Timestamps oder dedizierte Packages
  • Queue Jobs für schwere Operationen
  • Zentraler Cache (Redis) in Multi-Server-Setups

Du arbeitest an einem Laravel-Projekt mit komplexen Background-Prozessen oder Scheduling-Anforderungen? Ich helfe dir gerne bei Setup, Optimierung und Production-Deployment deiner Laravel-Anwendung.

Laravel Task Scheduling CronjobLaravelFreelancerWebentwicklungDüsseldorf