The Laravel team released v13.26.0 on August 18, 2026. The headline addition is a read-through filesystem driver that layers a primary disk over a fallback. Reads check the primary first, fall back to the secondary disk, and copy the file to the primary on the way through, so the primary fills lazily with files actually requested. Writes, deletes and listings go to the primary only. A copy => false option serves from the fallback without promotion, useful when pointing a development environment at production files. Promotion failures are swallowed by default; throw_on_promotion_failure => true surfaces them. Contributed by @taylorotwell in #61140, with the no-copy option by @jimbojsb in #61155.

The #[DebounceFor] attribute, introduced for queued jobs in Laravel 13.6, now works on queued event listeners. When the same event fires repeatedly, only the last dispatch inside the window runs the listener. A debounceId() method scopes the window per resource, and maxWait caps how long a busy stream can keep deferring the work. The debounce applies per listener, so other listeners on the same event still run every time. A debounced listener cannot also implement ShouldBeUnique; the dispatcher throws a LogicException, because uniqueness keeps the first dispatch while debouncing keeps the last. Contributed by @stevebauman in #61169.

Queue::forward() reroutes everything dispatched to a queue onto another queue, another connection, or both, configured once in a service provider with no changes to job classes or dispatch sites. It accepts single pairs or an array of mappings, and resolves through the same hook as Queue::route(), so forwards apply however the job reaches the queue. Contributed by @jackbayliss in #61188.

Three Process improvements come from @xurshudyan. Process pools and their results now implement IteratorAggregate (#61184); previously, foreach over ProcessPoolResults iterated public properties, of which there are none, so a loop meant to check exit codes silently checked nothing. An idle timeout now throws its own ProcessIdleTimedOutException instead of ProcessTimedOutException (#61182), separating a hung process from a slow one. The Process fake gained assertRanCount(), assertRanInOrder() and a recorded() filter that accepts a callback (#61193, #61197); the count and order assertions accept array commands as well as strings.

Eloquent gained orWhereKey() and orWhereKeyNot(), replacing the orWhereIn('id', ...) fallback for primary key conditions in or branches (@calebdw, #61154). wherePivot() and orWherePivot() now accept a closure receiving a builder scoped to the pivot model, so scopes on a custom pivot class are callable from the relationship query (@calebdw, #61150). inOrderOf() accepts enums in its value list (@ziadoz, #61147), and relations expose a getRelatedClass() accessor (#61222).

Queue worker visibility improved. A new JobReleased event fires when a job is released back onto the queue from its handler or from middleware such as WithoutOverlapping; the older JobReleasedAfterException only covered releases caused by a throw (#61108). Workers also print a notice when a consumed queue is paused and when it resumes, since a paused worker previously just went silent and read as a hang (#61142). Both are by @jackbayliss.

Other changes: Guzzle 8 is supported alongside Guzzle 7 (#60321). db:seed --class=SpecificSeeder shows the RUNNING/DONE progress output nested seeders already had (#61186). Redis got a hardening pass: paused-queue checks avoid cross-slot cluster reads, cache tag pruning scans every master node and no longer loops forever on stale tags, failed pipelines leave the connection usable, the phpredis client is rebuilt after cluster response errors, and some commands retry transient failures. The Cloud queue driver exposes managedQueues(), managed queue events promote nested data, and timed-out cloud agent long-polls are retried. throwUnless() no longer silently does nothing in a case where it should throw, and Request input key order is preserved when merging files. SQL Server respects readonly=false, Postgres JSON path attributes escape single quotes, and array JSON:API query parameters no longer cause a TypeError. On the dev side, the pail command registers only when Pail is installed, artisan dev stops repeatedly asking to install @laravel/multiplex, session errors keep the original assertion message, a setTestNow() reuse issue with now() was fixed, and expectsQuestion() allows array answers.

No breaking changes are expected for typical applications. Two edges: a listener carrying #[DebounceFor] throws a LogicException if it also implements ShouldBeUnique, and the whereKey()/whereKeyNot() internals were consolidated in #61154, which only matters if you extend the Eloquent builder and override those methods.