Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
YouTube Security VideosNutanix advances legacy and AI app management with AMD(01.10.2026 um 16:00 Uhr)
•
YouTube Security VideosPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••••
Videos & KonferenzenPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••
Sicherheitslücken (CVE)USN-8857-1: KCoreAddons vulnerability(01.10.2026 um 12:48 Uhr)
•••
YouTube Security VideosNutanix advances legacy and AI app management with AMD(01.10.2026 um 16:00 Uhr)
•
YouTube Security VideosPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••••
Videos & KonferenzenPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••
Sicherheitslücken (CVE)USN-8857-1: KCoreAddons vulnerability(01.10.2026 um 12:48 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

Building Elegant Batch Jobs in Laravel with Clean Architecture

Introduction When you need to process millions of records, the naive approach—looping through everything in a single job—quickly fails. A better way is to bre…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!




Introduction



When you need to process millions of records, the naive approach—looping through everything in a single job—quickly fails. A better way is to break processing into small, repeatable batches.



In this article, we’ll build a generic batch job pattern for Laravel that’s:




  • safe to serialize in the queue,

  • dependency-injection friendly,

  • clean and extensible.



No reflection tricks, no magic container calls—just solid code.






The Core Idea



Each batch job:




  1. Executes one iteration (limit items starting from offset).

  2. Reschedules itself if there’s more work to do.

  3. Delegates business logic to a handler implementing a shared interface.









Step 1 — The Handler Interface






namespace App\Foundation\Jobs\Batch;

use Illuminate\Support\Carbon;

interface BatchJobHandler
{
/**
* Process one batch.
* Must return the number of processed items.
*/

public function handle(Carbon $momentAt, int $limit, int $offset): int;
}






Every batch operation implements this interface.

It’s explicit and easy to test.





Step 2 — The Base Class





namespace App\Foundation\Jobs\Batch;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Carbon;
use function dispatch;
use function now;

abstract readonly class BatchJob implements ShouldQueue
{
public function __construct(
public string $momentAt,
public int $limit = 5000,
public int $offset = 0,
) {}

protected function handleAndDispatchNext(BatchJobHandler $handler): void
{
$handledCount = $handler->handle(
Carbon::parse($this->momentAt),
$this->limit,
$this->offset,
);

if ($handledCount < $this->limit) {
return; // no more data
}

dispatch(new static(
$this->momentAt,
$this->limit,
$this->offset + $this->limit
))->delay(now()->addSecond());
}
}





Key points:




  1. Only primitive constructor arguments → safe for queue serialization.

  2. The handler returns how many records were processed.

  3. If the handler processes a full batch, the job automatically requeues the next iteration.





Step 3 — The Handler





namespace App\Modules\Orders\Commands;

use App\Foundation\Jobs\Batch\BatchJobHandler;
use Illuminate\Support\Carbon;
use App\Modules\Orders\Domain\Contracts\OrderRepository;

final readonly class CloseExpiredOrdersBatch implements BatchJobHandler
{
public function __construct(
private OrderRepository $orders,
) {}

public function handle(Carbon $momentAt, int $limit, int $offset): int
{
$expired = $this->orders->findExpired($momentAt, $limit, $offset);

foreach ($expired as $order) {
// either dispatch a job or process directly:
// dispatch(new CloseOrderJob($order->id, $momentAt));

$order->close($momentAt);
$this->orders->update($order);
}

return $expired->count();
}
}





Each handler focuses solely on domain logic for its batch slice.

The framework handles pagination and chaining automatically.





Step 4 — A Concrete Job





namespace App\Modules\Orders\Jobs;

use App\Foundation\Jobs\Batch\BatchJob;
use App\Modules\Orders\Commands\CloseExpiredOrdersBatch;

final readonly class CloseExpiredOrdersBatchJob extends BatchJob
{
public function handle(CloseExpiredOrdersBatch $command): void
{
$this->handleAndDispatchNext($command);
}
}






Laravel’s container automatically injects CloseExpiredOrdersBatch into handle().

The job itself doesn’t contain any business logic—only orchestration.





Step 5 — Kicking It Off



You start it like any other Laravel job:




dispatch(new CloseExpiredOrdersBatchJob(now()->toIso8601String()));






The system runs the first batch, counts processed items,

and queues the next one until no more work remains.









Why This Pattern Works



✅ Serializable: No objects in constructor.

✅ DI-friendly: Laravel injects handlers naturally.

✅ Reusable: The base class fits any batchable use case.

✅ Transparent: No container reflection magic—everything is explicit.






Conclusion



This pattern is a small, composable framework for scalable background processing in Laravel.

It keeps orchestration separate from business logic, uses native Laravel features, and remains fully testable.



If your queues ever need to handle thousands—or millions—of records, this approach will keep your jobs clean, safe, and elegant.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building Elegant Batch Jobs in Laravel with Clean Architecture

Thematisch verwandte Begriffe: Building, Elegant, Batch, Jobs · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag