Skip to content

← Writing

engineering

Laravel 9 and the New Yearly Release Cadence

· Jerwin Arnado

Archive note: this is a backdated post, written years later while rebuilding this site. It’s dated to the moment it covers, but the hindsight is real.

Laravel 9 landed on February 8, about five months later than the old schedule would have put it. The delay is the headline feature: Laravel is moving from two major releases a year to one major release per year, with version 9 deliberately pushed back to sit on top of Symfony 6’s components.

Why the cadence change is the real story

The old six-month major cycle meant “Laravel 7” projects became “legacy” before some of them launched. For agencies and client work — my world — version churn is a real line item: every major bump is upgrade testing, dependency negotiation, and a client conversation about paying for invisible work.

One major per year (with security fixes extending accordingly) means upgrade planning becomes an annual ritual instead of a recurring scramble. It also signals something about the framework’s age, in a good way: Laravel is no longer sprinting to add table-stakes features. It’s a mature platform optimizing for the people running real systems on it. Boring on purpose is what infrastructure is supposed to be.

After 8’s Jetstream drama, a calm, structural release is also just… nice.

What’s actually in the box

  • PHP 8.0 minimum. The floor rises, and the framework’s own internals now use the 8.x goodies — which means idiomatic modern PHP in the docs and generated code, not just permission to use it yourself.
  • Symfony Mailer replaces SwiftMailer. SwiftMailer is end-of-life; this is the biggest forced migration in the release. If you send mail (everyone sends mail), read this section of the upgrade guide twice.
  • Enum attribute casting & implicit route binding. Eloquent $casts to native enums, and route parameters that hydrate into enum instances — Route::get('/orders/{status}', ...) rejecting invalid statuses at the routing layer. The 8.1 enum story is now end-to-end.
  • Controller route groups. Route::controller(OrderController::class)->group(...) — small, tidies real files.
  • Anonymous migration classes by default. Kills the class-name-collision problem on long-lived projects. If you’ve ever renamed CreateUsersTable2, you know.
  • Flysystem 3 under the Storage facade — another check-the-upgrade-guide item if you do anything custom with disks.
  • Rendered mailable preview in the browser and assorted quality-of-life: str()/to_route() helpers, forced scope bindings, a new query builder interface that finally gives IDEs and static analysis a fighting chance with where() chains.

Upgrade posture

For client projects: no rush — Laravel 8 gets security fixes for a while yet, and the Mailer/Flysystem changes mean this isn’t a coffee-break upgrade for apps with custom mail or storage code. For anything greenfield: start on 9 without hesitation, PHP 8.1, enums everywhere.

The meta-note I keep coming back to: between PHP’s annual November release and Laravel’s new annual cycle, the stack now has a rhythm. Language in November, framework in Q1, ecosystem catches up by mid-year. You can plan a year of maintenance around that. For those of us who measure projects in years rather than sprints, predictability is the most underrated feature any platform ships.