Laravel 13.22 Ships: Debounce Fixes, QueueFake Improvements, and Stringable Everywhere
Laravel v13.22.0 released on July 24, 2026, and while it's not a headline-grabbing release, it's the kind of steady maintenance update that quietly makes everyday development smoother. Here's what actually matters for your day-to-day work.
QueueFake gets a new assertion helper
Testing queued jobs got a little easier. Queue::fake() now exposes creationTimeOfOldestPendingJob(), which is useful when you're asserting that a batch of jobs was queued in the expected order or within an expected window:
Queue::fake();
ProcessImport::dispatch($file);
$oldest = Queue::creationTimeOfOldestPendingJob();
expect($oldest)->not->toBeNull();
If you've ever written a workaround using reflection or manual timestamps to check job ordering in a test, this replaces it with a first-party method.
Fewer cache hits when debouncing with maxWait
If you use the debounce() helper (common in rate-limited notification or webhook-retry code), Laravel now reduces redundant cache lookups when a maxWait value is set. Previously, each debounce check could trigger an extra cache round-trip; that overhead is trimmed in 13.22, which matters if you're debouncing high-frequency events like keystroke-driven autosave or live search.
Stringable instead of Str::of() internally
Under the hood, the framework's own codebase has been migrating internal string handling to new Stringable() rather than calling Str::of() or the global str() helper. This is mostly a consistency and micro-performance cleanup rather than something you need to change in your own code — Str::of() isn't going anywhere — but it's a good nudge that Stringable is the "real" object underneath both helpers, and reads just as naturally:
(new Stringable('Laravel 13.22'))
->headline()
->append(' just shipped');
JobReleasedAfterException gets more context
When a queued job fails, gets caught by a catch() handler, and is released back onto the queue, Laravel now attaches the exception to the JobReleasedAfterException event. If you listen for that event to log or alert on release-after-failure behavior, you now have the actual exception instance to inspect instead of just the job payload:
Event::listen(function (JobReleasedAfterException $event) {
Log::warning('Job released after exception', [
'job' => $event->job->resolveName(),
'exception' => $event->exception->getMessage(),
]);
});
Small fixes worth knowing about
The release also fixes a PHP extension detection issue in the SQLite CI workflow and extracts shared PHP setup steps into a composite GitHub Action — both internal to the framework's own test suite, but a sign of the ongoing investment in Laravel's CI reliability across PHP versions.
None of these changes require action on your part. Run composer update laravel/framework and you're on 13.22 with no breaking changes to worry about — this is a "free upgrade" release.