php 43 lines · 7 steps

Debouncing Eloquent jobs in Laravel

A Project model that reschedules metric recalculation only when relevant fields change, using a cache token to debounce stale jobs.

Explained by highlit
1<?php
2 
3namespace App\Models;
4 
5use App\Jobs\RecalculateProjectMetrics;
6use Illuminate\Database\Eloquent\Model;
7use Illuminate\Support\Facades\Cache;
8 
9class Project extends Model
10{
11 protected $fillable = ['name', 'budget', 'status'];
12 
13 protected static function booted(): void
14 {
15 static::saved(function (Project $project) {
16 if (! $project->wasChanged(['budget', 'status'])) {
17 return;
18 }
19 
20 $project->scheduleMetricsRecalculation();
21 });
22 }
23 
24 public function scheduleMetricsRecalculation(int $delaySeconds = 30): void
25 {
26 $token = (string) now()->valueOf();
27 
28 Cache::put($this->debounceCacheKey(), $token, now()->addSeconds($delaySeconds + 10));
29 
30 RecalculateProjectMetrics::dispatch($this->id, $token)
31 ->delay(now()->addSeconds($delaySeconds));
32 }
33 
34 public function debounceIsStale(string $token): bool
35 {
36 return Cache::get($this->debounceCacheKey()) !== $token;
37 }
38 
39 protected function debounceCacheKey(): string
40 {
41 return "project:{$this->id}:metrics-debounce";
42 }
43}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Model events can trigger side effects only when the fields you care about actually change.
  2. 2A cache-stored token lets a delayed job detect whether it was superseded by a newer trigger.
  3. 3Debouncing bursts of writes into a single delayed job avoids redundant expensive work.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Debouncing Eloquent jobs in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code