Prevent Duplicate Work with Cache::withoutOverlapping()
Cache::withoutOverlapping()
Imagine an API endpoint that starts an expensive operation:
public function generateReport()
{
// Generate a large report...
}
If two requests arrive at almost the same time, both requests may start the same operation.
This can result in:
- Duplicate processing
- Unnecessary database queries
- Multiple files being generated
- Conflicting updates
Laravel provides a simple solution for this.
Use Cache::withoutOverlapping()
use Illuminate\Support\Facades\Cache;
Cache::withoutOverlapping('generate-report', function () {
// Generate report...
});
Laravel creates an atomic lock for the given key. If another execution tries to acquire the same lock while the first one is running, it won't execute concurrently.
Add a Lock Duration
You can control how long the lock should remain valid:
Cache::withoutOverlapping(
'generate-report',
function () {
// Generate report...
},
lockFor: 120
);
Here, the lock can remain active for up to 120 seconds.
Control How Long to Wait
You can also specify how long another execution should wait for the lock:
Cache::withoutOverlapping(
'generate-report',
function () {
// Generate report...
},
lockFor: 120,
waitFor: 5
);
The second execution can wait up to 5 seconds for the lock before Laravel gives up.
Real-World Example
Suppose your admin panel has a button to synchronize products from an external API.
Instead of allowing multiple clicks to start multiple synchronizations:
Cache::withoutOverlapping('product-sync', function () {
$this->syncProducts();
});
Now only one product synchronization can run at a time.