Two events on a single day: On September 23, 2026, the Laravel team released version 13.33.0, and just one day later PHP 8.6 hit its RC1 milestone on schedule. Anyone looking at these two pieces of news in isolation is missing the real point. For teams running production Laravel applications, two timelines are converging here that need to be planned together over the coming weeks.
Laravel 13.33 brings six practical improvements focused mainly on performance, data integrity, and operational safety in the queue system. At the same time, the PHP 8.6 roadmap shows that developers don’t have much time left to prepare their compatibility tests. This article puts both developments in context, explains the most important changes in detail, and offers an assessment of how teams should proceed now.
Table of Contents
Key Takeaways
- Laravel 13.33.0 was released on September 23, 2026, and includes a tagged memoized cache, the new #[Refreshes] attribute, and nullable casts for JSON columns, among other things.
- Migrations for indexes and foreign keys can now be run via inplace() and lock() without a blocking table rebuild.
- A new Worker::$killOnTimeout flag gives queue workers the choice to either kill the process on timeout or throw an exception instead.
- PHP 8.6 reached RC1 on September 24, 2026, with General Availability planned for November 19, 2026. The headline feature is Partial Function Application (PFA).
- Laravel 14 is already taking shape on the master branch: PHP 8.4 as the minimum requirement, Route::query(), and authorize() throwing an exception instead of returning a value.
Laravel 13.33 at a Glance: The New Release in Detail
The official changelog in the laravel/framework GitHub repository documents Laravel 13.33.0 as a regular minor release within the 13.x branch [1][3]. Unlike major versions, a point release like this doesn’t bring radical API breaks, but rather targeted improvements sourced from the community and contributed by developers such as Joost de Bruijn, Caleb White, Zein Ahmad, Sander Muller, Jack Bayliss, and Jenthe Noordsij.
What’s notable about Laravel 13.33 is that almost every change solves a concrete, everyday problem: cache overhead for tagged values, stale model data after saving, incorrect NULL comparisons on JSON columns, blocking database migrations, and risky behavior around queue timeouts. Anyone running production Laravel applications will recognize at least one of these situations from their own experience.
Tagged Memoized Cache: Fewer Cache Hits, More Performance
The memoized cache store (Cache::memo()) stores values in memory within a single request so repeated reads don’t hit the cache backend every time. Until now, though, this store lacked a tags() method. Developers had to manually wrap tagged cache calls in a second Cache::store(‘array’) lookup to achieve the same effect.
With Joost de Bruijn’s contribution, that changes fundamentally: Cache::memo()->tags([…]) now enables the same memoization effect for tagged values. A read hits the actual cache backend only once per request; every subsequent access comes straight from memory. Pull request #61593 describes the implementation in detail. For applications with many repeated, tagged cache lookups within a single request — think complex dashboard views — this means fewer round-trips to the cache server, and potentially measurable latency gains.
The #[Refreshes] Attribute: Automatically Fresh Model Data
A common problem in Eloquent applications: columns like virtualAs or storedAs are computed by the database itself, not by PHP code. After a create or update, the in-memory model doesn’t automatically reflect these values — they stay empty or stale until someone explicitly calls refresh().
Caleb White contributed the new #[Refreshes] attribute and the matching $refreshes property for exactly this reason (pull request #61523). If a model class is annotated with, for example, #[Refreshes(‘name’)], Laravel automatically reloads the specified column from the database after every create or update. In the changelog’s example, this means that after User::create(), $user->name directly contains the value computed by the database, without developers having to manually call refresh(). This reduces sources of error especially in codebases that rely heavily on database-generated columns.
Nullable Casts for AsCollection and AsArrayObject
A subtle but practically relevant bug affected the AsCollection and AsArrayObject casts. If null was assigned to a corresponding attribute, Laravel previously stored the JSON string “null” in the column — not an actual database NULL. The consequence: queries using whereNull() never found the affected row, because the column technically wasn’t NULL, but a string containing “null”.
Zein Ahmad fixed this behavior with an opt-in nullable() mode (pull request #61596). When AsCollection::nullable() or AsArrayObject::nullable() is configured on the cast, Laravel actually writes a real SQL NULL to the column when null is assigned. Since this behavior is opt-in, existing code remains unchanged — teams can migrate selectively wherever NULL comparisons in WHERE clauses matter.
Index Migrations Without Table Locks: inplace() and lock()
Migrations that change indexes or foreign keys are often considered risky in production MySQL databases because they can trigger a blocking table rebuild. Sander Muller introduced two new modifiers with pull request #61602 that address exactly this risk: inplace() and lock().
With inplace(), a migration can explicitly instruct MySQL to use ALGORITHM=INPLACE; with lock(), it can additionally enforce LOCK=NONE. An example from the changelog shows the syntax:
$table->index('foo', 'foo_index')->inplace()->lock('none');
Both modifiers work not only on index(), but also on unique(), primary(), fullText(), spatialIndex(), and foreign(). For teams that need to modify large tables without downtime, this is a direct lever for shortening migration windows in production systems.
“Migrations that previously required a maintenance window can now be run deliberately without a blocking rebuild using the new modifiers.”
Worker Timeout Handling: More Control Over Queue Jobs
In Laravel’s queue system, a job that exceeds its configured timeout kills the entire worker process by default. The supervisor then starts a new worker — a robust but blunt behavior that prevents any cleanup work the job might be doing.
Jack Bayliss introduced the new Worker::$killOnTimeout flag with pull request #61591. Setting it to false makes the worker throw a TimeoutExceededException instead when the timeout is exceeded, giving the job a chance to clean up gracefully while the worker process keeps running.
This flexibility comes with an important warning, though: a job whose handle() method wraps its entire body in a broad try/catch can accidentally catch and swallow the TimeoutExceededException. In that case, the system no longer properly notices the timeout at all. Teams enabling this flag should carefully review their exception-handling strategy in jobs.
New Test Helpers: mockArtisan() and realArtisan()
The well-known test helper $this->artisan() traditionally serves two purposes at once in Laravel: it can both set expectations for an Artisan command and actually execute the command. This dual role occasionally leads to confusion in tests about which behavior is currently in effect.
Jenthe Noordsij introduced two specialized helpers with pull request #61588: mockArtisan() always returns a PendingCommand for expectations, while realArtisan() is guaranteed to execute the command and returns the exit code as an int. This clear separation makes test code more readable and reduces confusion in larger test suites where both use cases occur.
More Changes in Laravel 13.33.0
Beyond the six central improvements, Laravel 13.33 includes several smaller but relevant adjustments:
| Change | What it means for developers |
|---|---|
| Support for Laravel Cloud read replicas on PostgreSQL | Load distribution for read operations in cloud environments |
| valkey:// and valkeys:// protocol support | Direct compatibility with Redis-compatible Valkey servers |
| Fix for SQLite schema dumps containing shadow tables | More reliable schema exports in test environments |
| Test support for MariaDB 12.3 | Broader database coverage in the CI pipeline |
These points may look small at first glance, but they add up to a release that directly touches the daily work of many teams — especially those already using Valkey or Laravel Cloud [2][4].
PHP 8.6 Reaches RC1: Roadmap and Headline Feature
While the Laravel team was working on version 13.33, the next major PHP milestone was approaching in parallel: after a hard feature freeze on September 22, 2026, PHP 8.6 reached RC1 status on schedule on September 24, 2026. (More background in our in-depth PHP 8.6 article.) The official PHP wiki release plan, as cited by digitalmatters.me, lists the next steps as RC2 on October 8, RC3 on October 22, and RC4 on November 5, 2026, with General Availability on November 19, 2026.
The central feature of PHP 8.6 is Partial Function Application, or PFA for short. It lets you create a closure by calling a function with placeholders instead of actual arguments: a single question mark (?) marks an open argument position, and three dots (…) stand for all remaining arguments. The corresponding RFC passed unanimously with 33 votes to 0 — a clear signal that the PHP community regards this feature as a genuinely useful addition to the language.
For Laravel developers, the timeline matters: RC phases exist explicitly to find regressions, not for production use. Laravel 13.33’s compatibility with PHP 8.6 RC1 should currently be considered experimental and not confused with production-ready support.
Laravel 13.33 and PHP 8.6 RC1: Compatibility and Test Strategy
Laravel 13 was developed and tested against currently officially supported PHP versions, not against release-candidate versions of an upcoming major version [6][9]. Concretely, this means: teams running Laravel 13.33 in production today should use PHP 8.6 RC1 exclusively in isolated test environments, never in production systems.
A sensible test strategy for the coming weeks involves several steps:
- Set up a separate CI pipeline running PHP 8.6 RC1 alongside your existing production PHP version.
- Run the full test suite regularly against every new release-candidate stage (RC2, RC3, RC4) to catch regressions early.
- Pay particular attention to areas that could be affected by language features like Partial Function Application, such as callback-based APIs and functional helper functions.
- Check Composer dependencies and third-party packages for explicit PHP version constraints before considering an upgrade.
This caution pays off once PHP 8.6 reaches General Availability in November 2026. Teams that test now avoid unpleasant surprises during the later production migration.
Outlook on Laravel 14
Parallel to the current point releases, the master branch already shows where the next major version is heading. A Laravel 14 preview roundup by Paul Redmond, cited in the “A Day With Laravel” newsletter from September 23, 2026, names three central points: PHP 8.4 becomes the new minimum requirement for Laravel 14, a new Route::query() extends the routing system, and $user->authorize() will throw an exception instead of merely returning false.
These changes point toward clearer, stricter error handling and a raised PHP minimum version — both topics teams should already be factoring into their long-term roadmap for 2027 and beyond. Exactly how Laravel 14 will ultimately differ from Laravel 13.33 remains an assessment based on the current state of development until the official announcement.
Conclusion
Laravel 13.33 shows that a minor release is by no means insignificant: the tagged memoized cache, the #[Refreshes] attribute, nullable casts, lock-free index migrations, the flexible worker timeout behavior, and the new test helpers each solve a concrete problem from everyday development. At the same time, the parallel arrival of PHP 8.6 RC1 is a reminder that compatibility work isn’t a one-time project, but an ongoing process.
Clear next steps follow for development teams: test Laravel 13.33 promptly in a staging environment, adopt the new features selectively where they deliver real value, and in parallel build an isolated test pipeline for PHP 8.6 RC1. Teams that pursue both tracks now — separately but in coordination — will be well prepared both for PHP 8.6’s General Availability in November 2026 and for the upcoming move to Laravel 14.
References
[1] Laravel – https://releasebot.io/updates/laravel [2] Releases – https://laravel-news.com/tag/releases [3] Releases – https://laravel.com/framework/docs/master/releases [4] News – https://laravel-news.com/category/news [6] Laravel – https://endoflife.date/laravel [9] Releases – https://laravel.com/framework/docs/13.x/releases







