Read-Through Disks and Debounced Listeners in Laravel 13.26
Laravel #Laravel 13.26 #Filesystem #Queue #Eloquent #Laravel Release

Read-Through Disks and Debounced Listeners in Laravel 13.26

4 min read Mohamed Said Mohamed Said

What's New in Laravel 13.26

Laravel v13.26.0 was released on August 18, 2026. The headline additions are a read-through filesystem driver, debouncing support for queued event listeners, and a Queue::forward() helper. Here is a practical breakdown of every notable change.


Read-Through Filesystem Disks

A new read-through driver layers a primary disk over a fallback. On the first read of any file, Laravel serves it from the fallback and promotes a copy to the primary, so the primary fills lazily with only the files that are actually requested. Writes, deletes, and directory listings always target the primary.

'assets' => [
    'driver'   => 'read-through',
    'primary'  => 'r2',
    'fallback' => 'legacy-s3',
],

Set copy => false to serve from the fallback without promoting anything — useful in development environments pointed at production files. Promotion failures are silently swallowed by default; set throw_on_promotion_failure => true to surface them. Contributed by @taylorotwell in #61140.


Debounced Queued Listeners

The #[DebounceFor] attribute, which already worked on queued jobs since Laravel 13.6, now applies to queued event listeners. When the same event fires repeatedly, only the last dispatch within the window executes the listener.

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\Attributes\DebounceFor;

#[DebounceFor(30, maxWait: 120)]
class UpdateProductSearchIndex implements ShouldQueue
{
    public function debounceId(ProductUpdated $event): string
    {
        return (string) $event->product->getKey();
    }

    public function handle(ProductUpdated $event): void
    {
        // reindex once, with the latest state
    }
}

debounceId() scopes the window per resource, and maxWait caps how long a busy stream can keep deferring work. A listener carrying #[DebounceFor] cannot also implement ShouldBeUnique; the dispatcher throws a LogicException because the two contracts conflict. Contributed by @stevebauman in #61169.


Queue::forward()

Queue::forward() reroutes all jobs dispatched to a named queue onto a different queue, connection, or both — with no changes to job classes or dispatch call sites.

Queue::forward('reports', 'reports.fifo', 'cloud'); // rename + move connection
Queue::forward('payments', connection: 'cloud');    // keep name, move connection
Queue::forward('updates', 'notifications');         // rename on same connection

Queue::forward([
    'reports' => 'reports.fifo',
    'emails'  => 'emails.fifo',
], connection: 'cloud');

Forwards resolve through the same hook as Queue::route(). Contributed by @jackbayliss in #61188.


Process Improvements

  • Iterable process poolsProcessPoolResults now implements IteratorAggregate, so foreach loops over exit codes actually work.
  • ProcessIdleTimedOutException — idle timeouts now throw their own exception, separate from ProcessTimedOutException, so you can distinguish a hung process from a slow one.
  • New fake assertionsassertRanCount(2), assertRanInOrder([...]), and recorded() with a callback filter make process testing more precise.

Eloquent Builder Additions

  • orWhereKey() and orWhereKeyNot() complement the existing whereKey() pair for primary-key conditions in OR branches.
  • wherePivot() and orWherePivot() now accept a closure scoped to the pivot model, enabling custom pivot scopes in relationship queries.
  • inOrderOf() accepts enums in its value list, consistent with enum support elsewhere in the query builder.

Queue Worker Visibility

A JobReleased event now fires when a job is released back to the queue from middleware such as WithoutOverlapping — previously only JobReleasedAfterException existed, leaving overlap-triggered releases invisible. Workers also print a notice when a queue is paused or resumes, and report the paused state on startup.


Other Notable Fixes

  • Guzzle 8 is now supported alongside Guzzle 7.
  • Several Redis cluster hardening fixes: cross-slot reads eliminated, cache tag pruning covers all master nodes, stale-tag infinite loops resolved, and failed pipelines leave the connection usable.
  • throwUnless() no longer silently skips a case where it should throw.
  • Single quotes are correctly escaped in Postgres JSON path attributes.

Key Takeaways

  • The read-through driver enables zero-downtime, lazy bucket migrations with a two-line config change.
  • #[DebounceFor] on listeners eliminates redundant reindex or recalculation jobs during high-frequency event bursts.
  • Queue::forward() lets you restructure queue topology from a service provider without touching job classes.
  • Separate idle and wall-clock timeout exceptions make process error handling more precise.
  • orWhereKey() and closure-based wherePivot() clean up common Eloquent query patterns.

Source: Read-Through Disks and Debounced Listeners in Laravel 13.26 — Laravel News

Found this useful?

Frequently Asked Questions

3 questions
Q01 What does the Laravel 13.26 read-through filesystem driver do?
It layers a primary disk over a fallback disk. On the first read of a file, Laravel serves it from the fallback and copies it to the primary, so the primary fills lazily with only the files that are actually accessed. Set `copy => false` to skip promotion entirely, or `throw_on_promotion_failure => true` to surface copy errors.
Q02 Can a queued listener use both #[DebounceFor] and ShouldBeUnique in Laravel 13.26?
No. The dispatcher throws a LogicException if a listener carries both, because ShouldBeUnique keeps the first dispatch while DebounceFor keeps the last — the two contracts are mutually exclusive.
Q03 How does Queue::forward() differ from editing job dispatch calls?
Queue::forward() is registered once in a service provider and applies to every job dispatched to the named queue, regardless of where in the codebase the dispatch originates. No job classes or dispatch sites need to be modified.

Continue reading

More Articles

View all