Laravel 12 end of life is no longer a future problem. Bug fixes stopped on August 13, 2026 — about four weeks ago as I write this. Security fixes continue until February 24, 2027, which gives you roughly twenty-four weeks of runway and then nothing.
That is a genuinely comfortable window if you start now, and a genuinely uncomfortable one if you discover it in January. This post is not a how-to for the upgrade itself; that already exists in upgrading to Laravel 13. This one is about the lifecycle and the timing decision: what the support policy actually guarantees, what "security-only" means on an ordinary Tuesday, and how to decide whether your team moves in October, December, or Q1 2027.
The Laravel Version Support Policy, in Plain Terms
Laravel's support policy is two numbers, and they have been stable for years:
- 18 months of bug fixes from the release date
- 24 months of security fixes from the release date
That leaves a six-month tail at the end of every major version where the framework is patched for vulnerabilities and nothing else. Majors ship roughly every Q1, so at any given moment you have one actively maintained version, one in its security-only tail, and everything older fully dead.
Two details that trip up planning:
The clock starts at release, not at your adoption. If you upgraded to Laravel 12 in late 2025, you did not get 18 months. You got whatever was left. Teams that habitually adopt a major six or nine months late are running on a shorter fuse than they think.
First-party packages do not get a tail at all. The policy is explicit that for additional libraries — Horizon, Sanctum, Cashier, Nova, Telescope, Scout — only the latest major release receives bug fixes. There is no "security-only" period for the ecosystem around the framework. Once the current major of Horizon requires Laravel 13, the Laravel 12-compatible line is simply done.
That second point is the one that actually forces most timelines, and I will come back to it.
Laravel Support Dates: 11, 12, and 13
Here is the current state, taken from the official policy table. Check it yourself rather than trusting this snapshot in six months.
| Version | Supported PHP | Released | Bug Fixes Until | Security Fixes Until | Status today |
|---|---|---|---|---|---|
| 11 | 8.2 – 8.4 | Mar 12, 2024 | Sep 3, 2025 | Mar 12, 2026 | End of life |
| 12 | 8.2 – 8.5 | Feb 24, 2025 | Aug 13, 2026 | Feb 24, 2027 | Security fixes only |
| 13 | 8.3 – 8.5 | Mar 17, 2026 | Q3 2027 | Mar 17, 2028 | Actively maintained |
Three conclusions follow immediately.
Laravel 11 is fully dead. It stopped receiving security patches on March 12, 2026. If you are on 11, this post's timeline does not apply to you — you are already in remediation, not planning, and you should be scoping honestly against what a Laravel upgrade actually costs.
Laravel 12 is in its final six months. You have security patches and nothing else until February 24, 2027.
Laravel 13 needs PHP 8.3 minimum. Laravel 12 runs on PHP 8.2; Laravel 13 does not. For a lot of teams this is the real work — the framework hop is small, and the runtime hop underneath it is not.
What "Security-Only" Actually Means Day to Day
This is where teams either overreact or underreact, usually depending on whether the person reading the table is an engineer or an auditor.
What you still get
Real security patches, backported to the 12.x branch, published through the normal release process and picked up by an ordinary composer update. If a CVE lands in the framework between now and February 24, 2027, you get a fix. Laravel's security handling is good and this is not a token guarantee.
What you no longer get
Everything else. A bug in the query builder that produces wrong results on your specific database version? Not fixed on 12.x. A regression in queue retry behavior? Not fixed. A framework method that leaks memory under Octane? Not fixed. The answer to all of these is now "upgrade to 13," and that answer arrives at the moment you are least able to act on it — mid-incident.
That is the practical cost of the security-only window. It is not that you are unsafe. It is that your escape hatch for any non-security framework bug is a major version upgrade, so an unplanned production issue can force an unplanned upgrade under time pressure. The whole point of moving deliberately is to never be in that position.
The risk that actually compounds: ecosystem drift
The framework itself is the stable part. The packages around it are not.
Within a few months of a major release, maintainers start dropping the old constraint. New majors of popular packages ship with "laravel/framework": "^13.0" and stop backporting. You do not notice this as a breakage — you notice it as a slow freeze:
composer updatestops moving. Your lockfile ossifies.- A
composer auditadvisory lands on a package whose fix is only in a major that requires Laravel 13. - A new integration you need has no Laravel 12-compatible release.
Each of those individually is survivable. Together they mean that by the time you have to upgrade, you are upgrading the framework and fifteen packages simultaneously, which is a categorically harder project than upgrading the framework alone. The cost of a Laravel upgrade rises the longer you wait, and it rises through your dependency graph, not through the framework.
The PHP 8.2 collision
There is a second deadline sitting right in the middle of this window. PHP 8.2 reaches end of life on December 31, 2026 — after Laravel 12's bug-fix cutoff and before its security cutoff. If you are on Laravel 12 and PHP 8.2, you have two expiries eight weeks apart, and the ordering matters. I wrote that plan up separately in PHP 8.2 end of life: what Laravel teams should do now, and the short version is: move PHP first, ship it on its own, then move the framework.
The mechanical reason is that Composer resolves php as a platform requirement, so on 8.2 the Laravel 13 update will not resolve at all. The better reason is attribution — one branch with both changes gives you a diff where every failure is ambiguous. The language-level details of the runtime hop are in PHP 8.3 to 8.5 for Laravel teams.
Where You Actually Stand: A 30-Minute Audit
Before you can decide when, you need to know how far. This is half an hour and it produces the number every subsequent conversation depends on.
Start with what the application reports about itself, not what the README claims:
# Framework version, PHP version, drivers, and cache state
php artisan about
# The runtime the CLI actually sees
php -v
# Is a Composer platform override lying about your real PHP floor?
composer config platform.php
Then find out what blocks the target. This one command is your estimate:
# Which packages cap you below Laravel 13?
composer why-not laravel/framework 13.0
# And which cap you below the PHP version Laravel 13 requires?
composer why-not php 8.3
composer why-not names every package whose constraint stands between you and the target. A short list means this is a two-week job. A list of fifteen, three of which are unmaintained, means you are scoping something else entirely.
For anything it names, find out who pulled it in before you decide what to do about it:
composer why spatie/laravel-permission
composer depends --tree barryvdh/laravel-debugbar
A blocker that is a direct dependency is a decision. A blocker four levels deep behind a package you barely use is often just a deletion.
Finish with a dependency health check:
# Only the packages you chose and own - ignore the transitive noise
composer outdated --direct
# Packages the maintainer has explicitly given up on
composer show --direct --outdated --format=json | grep -i abandoned
# Known vulnerabilities in your current lockfile
composer audit
Two signals to write down: how many direct dependencies are one or more majors behind, and how many are abandoned. Those two numbers, more than your application's size, predict how painful this will be.
The Decision Framework: Upgrade Now or Wait
There is no universal answer, but there is a defensible one per team. The variables that matter are how much runway you need, how quickly you can ship, and what happens if you are wrong.
| Your situation | Recommendation | Reasoning |
|---|---|---|
Laravel 12 + PHP 8.3/8.4/8.5, clean why-not output, good test coverage |
Upgrade now. Q4 2026. | The work is small and shrinks your risk to zero. Do not carry this into 2027. |
| Laravel 12 + PHP 8.2 | PHP first, October–December. Framework in Q1 2027. | Two deadlines, eight weeks apart. Sequence them; do not merge them. |
| Laravel 12, 5+ blocking packages | Start dependency remediation now, upgrade Q1 2027. | Package work is the long pole and it parallelizes badly. |
| Regulated (PCI/SOC 2/HIPAA) or enterprise-procurement exposed | Upgrade now, non-negotiable. | You will be asked to attest to supported components. "Security-only" is defensible; "end of life" is a finding. |
| Thin test coverage on critical paths | Build the test gate first, then upgrade. | The upgrade is not your risk. Not knowing whether it worked is. |
| Laravel 11 or older | This is remediation, not planning. | Already unsupported. See the staged upgrade playbook. |
| Freeze through Q4, small team, low-traffic internal app | Q1 2027 with a named owner and a board-visible date. | Legitimate — but only with a date attached. |
The framing I use with CTOs: there is no scenario where waiting past February 24, 2027 is the cheaper option. Every week past that date adds unpatched exposure with no upper bound and no scheduled relief. The only real question is which quarter, and which workstream it displaces.
One more consideration for anyone tempted to skip 13 and wait for the next major: Laravel's documented cadence is one major release per year, roughly Q1. A Laravel 14 in early 2027 is the reasonable expectation, but the release date and its PHP floor are not published yet. Waiting to skip a version means spending your entire security window betting on an unannounced date, and landing on a brand-new major before the ecosystem has caught up. I would not do it.
The Timeline: Twenty-Four Weeks to February 24
Working backwards from February 24, 2027, reserving the last three weeks as buffer. Effort estimates are for a mid-sized Laravel 12 application — call it 60k–150k lines, 40 or so direct dependencies, a test suite that mostly passes.
| Window | Milestone | Effort | Exit criteria |
|---|---|---|---|
| Sep 14 – Sep 25 | Audit and scoping | 0.5–1 day | composer why-not triaged; every blocker has an owner |
| Sep 28 – Oct 16 | Test gate | 3–8 days | Critical paths covered; PHPStan baseline frozen; CI fails on deprecations |
| Oct 19 – Nov 13 | Dependency remediation | 2–15 days | Every blocking package upgraded, replaced, forked, or deleted |
| Nov 16 – Dec 11 | PHP hop (only if on 8.2) | 5–15 days | Green on target runtime; shipped and soaked independently |
| Jan 4 – Jan 15 | Framework upgrade branch | 1–5 days | composer update resolves; suite green on Laravel 13 |
| Jan 18 – Jan 29 | Staging soak | 3–5 days | 72h+ with queues, scheduler, and nightly jobs running |
| Feb 1 – Feb 12 | Staged production rollout | 2–4 days | 100% of traffic, error rate and p95 flat |
| Feb 15 – Feb 24 | Buffer | — | You are done before the date, not on it |
If your why-not output was clean and you are already on PHP 8.3+, collapse this to about three weeks and ship it in October. The schedule above is sized for the messy case, and the messy case is more common than anyone admits.
For a full breakdown of what drives the effort numbers up or down, that is the subject of what a Laravel upgrade actually costs.
Guardrails: The Test Gate and the Staged Rollout
Two things separate an upgrade that lands quietly from one that becomes an incident.
Make the test suite an actual gate
Coverage is not the point. Attributable failure is the point. Before you touch composer.json, freeze your current static-analysis state so any new error is genuinely new:
vendor/bin/phpstan analyse --generate-baseline
Then make deprecations fail the build, so framework-level warnings surface in CI instead of accumulating silently in production logs:
# Pest
vendor/bin/pest --fail-on-deprecation --fail-on-warning
# PHPUnit
vendor/bin/phpunit --fail-on-deprecation --fail-on-warning --fail-on-notice
A deprecation that does not fail the build is a deprecation nobody ever fixes. That is precisely how teams arrive at a major version bump with four hundred warnings and no idea which ones matter.
Change the constraint deliberately
The framework bump itself is one line, and it should be the only meaningful line in the diff:
{
"require": {
"php": "^8.3",
"laravel/framework": "^13.0"
}
}
# Resolve the framework and first-party packages together, nothing else
composer update laravel/framework laravel/tinker \
--with-all-dependencies
# Confirm the result can actually install on your target runtime
composer check-platform-reqs
Keep unrelated dependency updates out of this branch. If a stray composer update pulls in packages requiring Laravel 13 features you have not adopted, your rollback lockfile is no longer installable and your rollback has quietly stopped existing.
Laravel Shift versus doing it manually
Laravel Shift is worth the money for the mechanical portion — skeleton config diffs, renamed classes, deprecated helper calls — and it is cheap relative to an engineer-day. It is not a substitute for the two parts that actually consume your timeline: dependency remediation and validating behavior under load. Shift is a fast start to the boring half. Budget for the interesting half either way.
Roll out in stages
Same shape every time, and the ordering is deliberate:
- CI green on Laravel 13 with deprecations failing the build.
- Staging with production-shaped data, running the full stack — queue workers, scheduler, Horizon — for at least 72 hours so nightly and weekly jobs actually execute.
- Canary one queue worker pool. Workers exercise your heaviest code paths, and a failure degrades throughput instead of user-facing availability. Drain queues before switching pools, since serialized job payloads written by one version get read by another.
- Ramp web traffic 10% → 50% → 100%, watching error rate, p95 latency, and memory per worker at each step.
- Watch the slow query log, not just the error rate. Framework upgrades occasionally change query shapes in ways that pass every test and quietly double your database load — worth reading the results against Laravel database performance.
If you run Octane, add an explicit load-profile step. Long-lived workers surface state leaks that a per-request application never shows, and your application server is a hard dependency on both the PHP and framework versions.
Frequently Asked Questions
Is Laravel 12 end of life right now? Not fully. Laravel 12 stopped receiving bug fixes on August 13, 2026 and continues to receive security fixes until February 24, 2027. It is in the security-only window. It reaches true end of life on February 24, 2027.
What actually happens on February 24, 2027?
Nothing visible. Your application keeps running. What changes is that no future Laravel security release will include a patch for the 12.x branch, so any subsequently disclosed framework vulnerability stays unpatched in your dependency tree permanently.
How long do I have to upgrade from Laravel 12 to 13? About twenty-four weeks from September 10, 2026. That is enough time to do it properly, including a separate PHP upgrade if you need one, provided you start the audit now rather than in January.
Can I skip Laravel 13 and wait for Laravel 14? I would not. Laravel ships majors roughly annually in Q1, but Laravel 14's date and PHP floor are not published. Waiting means gambling your entire security window on an unannounced release and then adopting a major before the package ecosystem has caught up. Upgrade to 13 now; 13 is supported until March 2028.
Does Laravel 12 support PHP 8.5? Yes. Laravel 12 supports PHP 8.2 through 8.5. That is useful: you can move all the way to PHP 8.5 without touching the framework, which makes the Laravel 13 hop a separate, smaller project.
Do I have to upgrade PHP before Laravel 13? If you are on PHP 8.2, yes — Laravel 13 requires 8.3 minimum, and Composer will refuse to resolve otherwise. If you are on 8.3 or above you are already clear.
What if I am still on Laravel 11? Laravel 11 reached full end of life on March 12, 2026. You are running an unsupported framework today. Treat it as a security remediation with a named owner and a date, and work through the staged approach in the legacy Laravel migration playbook.
Does the support policy cover Horizon, Sanctum, and Cashier too? No. The policy states that for additional first-party libraries, only the latest major release receives bug fixes. There is no security-only tail for the ecosystem — which is usually what forces the timeline before the framework date does.
Key Takeaways
- Laravel 12 bug fixes ended August 13, 2026. Security fixes end February 24, 2027. You are in the final six-month window with roughly twenty-four weeks of runway.
- Security-only means your escape hatch for any non-security framework bug is a major upgrade — one you will be doing under pressure if you wait.
- Laravel 11 is fully end of life as of March 12, 2026. Laravel 13 is supported until March 17, 2028 and requires PHP 8.3 minimum.
- Ecosystem drift is the real cost of waiting. First-party packages get no security-only tail, and third-party maintainers drop old constraints fast.
composer why-not laravel/framework 13.0is your estimate. Package compatibility, not application code, is what stalls these projects.- If you are on PHP 8.2, sequence it: runtime first, framework second. Two deadlines eight weeks apart, and Composer will not let you merge them anyway.
- There is no scenario where waiting past February 24, 2027 is cheaper. The only question is which quarter.
Verify every date here against the Laravel support policy before you build a plan on it. Support windows are published well ahead of time, but a blog post is a map, not the territory.
If you would rather have a second opinion on the sequencing than discover the blockers in January, that is the kind of work I do — pre-upgrade audits, dependency triage, and running the migration while your team keeps shipping features. Send me your php artisan about output and your composer why-not laravel/framework 13.0 list; that is usually enough for a useful first answer.

Richard Joseph Porter
Senior Laravel Developer with 14+ years of experience building scalable web applications. Specializing in PHP, Laravel, Vue.js, and AWS cloud infrastructure. Based in Cebu, Philippines, I help businesses modernize legacy systems and build high-performance APIs.
Need Help Upgrading Your Laravel App?
I specialize in modernizing legacy Laravel applications with zero downtime. Get a free codebase audit and upgrade roadmap.
Related Articles
PHP 8.2 End of Life Is December 31, 2026: What Laravel Teams Should Do Now
PHP 8.2 end of life lands December 31, 2026. Here is the compliance risk, a dated migration plan for Laravel teams, and the rollback path if it goes wrong.
PHP 8.3 to 8.5 for Laravel Teams: The Upgrade Before the Upgrade
Upgrade PHP for Laravel the right way: a staged 8.3 to 8.4 to 8.5 path, the PHP 8.4 breaking changes that bite, CI matrix, canary rollout, and rollback.
Upgrading to Laravel 13: What Changed and What Breaks
A practical Laravel 13 upgrade guide: the breaking changes that actually bite, paths from Laravel 10, 11, and 12, an audit checklist, and realistic timelines.