Download the PHP package bouzentm/laravel-queue-debounce without Composer
On this page you can find all versions of the php package bouzentm/laravel-queue-debounce. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package laravel-queue-debounce
Laravel Queue Debounce
Dispatch-time debounce for Laravel queued jobs. One job per debounce window, atomic Redis gating, crash recovery.
Works with any Laravel queue driver: Redis, SQS, Database, etc.
The problem: Webhooks, event listeners, and real-time triggers fire multiple times for the same entity within seconds. Without debouncing, you get duplicate jobs flooding your queue.
This package gates at dispatch time using Redis GETSET — only 1 job enters the queue per debounce window. Subsequent calls are no-ops (nothing queued).
How it works
- First
::debounce()→ sets Redis key, queues job with delay - Subsequent calls within the window → Redis key exists, skip (nothing queued)
- Job executes → middleware cleans up Redis key
- Next call → starts a new debounce window
vs ShouldBeUnique / ShouldBeUniqueUntilProcessing
| Feature | ShouldBeUnique | This package |
|---|---|---|
| Lock held during | Processing only | Configurable delay window |
| Lock released | After handle() finishes | After handle(), only if not released |
| Crash recovery | Lock expires via TTL | Detects expired timestamps, re-queues |
| Queue stats | 1 job (clean) | 1 job (clean) |
release() / $tries / failed() |
Works | Works |
| Cooldown after execution | No | Yes (delay window) |
Installation
Requirements
- PHP 8.3+
- Laravel 12+
- Redis (phpredis extension)
Usage
Basic usage
Multiple arguments
The debounce key is defined by you, so you control granularity:
Merging with other middleware
The trait defines middleware() which cleans up the Redis key after handle() runs. If your job needs additional middleware (e.g. WithoutOverlapping), override middleware() and merge with debounceMiddleware():
Configuration
| Property | Default | Description |
|---|---|---|
$debounceDelay |
60 |
Seconds to delay execution. During this window, subsequent debounce() calls are no-ops. |
debounceKey() |
(abstract) | Unique key for the debounce window. Include entity identifiers for proper scoping. |
Custom debounce delay (PHP 8.4+)
The trait declares protected int $debounceDelay = 60. On PHP 8.4+, redeclaring the property in your job with a different default causes a FatalError:
Set the delay in your constructor instead:
Crash recovery
If a job crashes without cleanup (worker killed, OOM, etc.), the Redis key holds an expired timestamp. The next debounce() call detects this and re-queues:
Release-safe cleanup
If your job calls $this->release() (e.g. to retry later), the Redis key is not deleted — the debounce window stays active. The key is only cleaned up after a successful execution that doesn't release back to queue.
How it works internally
Uses Redis GETSET for atomic dispatch-time gating:
GETSET key new_timestamp— atomically reads old value, writes new- If old value is
false(no job pending) or expired (crashed) → queue the job - If old value is in the future → job already pending, skip
- Middleware runs after
handle()→ deletes key only if not released → opens window for next cycle
The first event triggers execution after the delay. Subsequent events during the window are dropped.
Testing
License
MIT
All versions of laravel-queue-debounce with dependencies
illuminate/bus Version ^12.0
illuminate/queue Version ^12.0
illuminate/redis Version ^12.0
illuminate/support Version ^12.0