# Laravel 12 vs 13: What Actually Changed, and When You Need to Upgrade

> Laravel 13 is a small upgrade with a few changes that matter: PHP 8.3, origin-aware CSRF protection, hardened cache unserialization and JSON session serialization. Here is the side-by-side, the support dates, and the upgrade items that can log your users out.

**Author:** Matt King | **Published:** October 6, 2026 | **Category:** Security

---

Laravel 13 was released on March 17, 2026. If you are still on Laravel 12, the short version is: the upgrade is small, there is no urgency for features, but the support clock is now running and a few of the changes have real security and session implications worth understanding before you start.

---

## Laravel 12 vs 13 at a glance

| | Laravel 12 | Laravel 13 |
|---|---|---|
| Released | February 24, 2025 | March 17, 2026 |
| PHP | 8.2 to 8.5 | 8.3 to 8.5 |
| Bug fixes until | August 13, 2026 (ended) | Q3 2027 |
| Security fixes until | February 24, 2027 | March 17, 2028 |

Dates are from the [official support policy](https://laravel.com/docs/13.x/releases). The important line is the third one: Laravel 12 no longer receives bug fixes. It still gets security patches until February 24, 2027, and nothing after that.

---

## What is new in Laravel 13

The release notes describe Laravel 13 as having minimal breaking changes. The headline additions:

- **PHP 8.3 minimum.** The biggest practical change for most teams. Check your servers, CI images and Docker base images first.
- **Laravel AI SDK.** A first-party package for text generation, agents, embeddings, images and audio across providers.
- **JSON:API resources.** First-party support for responses that follow the JSON:API specification.
- **Queue routing by class.** `Queue::route(...)` sends a job class to a connection and queue from one place instead of on every dispatch.
- **More PHP attributes**, such as `#[Middleware('auth')]` on controllers.
- **`Cache::touch()`** to extend an item's TTL without rewriting it.
- **Semantic and vector search** support.

None of these force you to change existing code. They are reasons to upgrade, not things that break when you do.

---

## The changes that matter for security

These come from the [Laravel 13 upgrade guide](https://laravel.com/docs/13.x/upgrade). They are the ones to read carefully. For a step-by-step version, see the [Laravel 13 security upgrade checklist](/blog/laravel-13-security-changes).

### CSRF becomes request forgery protection

The `VerifyCsrfToken` middleware is now `PreventRequestForgery`, and it adds origin-aware checks using the browser's `Sec-Fetch-Site` header on top of the token check. The upgrade guide rates this as high impact.

`VerifyCsrfToken` and `ValidateCsrfToken` still exist as deprecated aliases, so existing references keep working. What to check:

- Any code that extends or references `VerifyCsrfToken` by name, including test helpers that disable it.
- Your exemption list. Laravel 13 adds a `preventRequestForgery(...)` method for configuring the middleware in `bootstrap/app.php`. Review your exemptions while you are there: CSRF exemptions added "temporarily" for a webhook have a way of covering far more routes than intended.
- Cross-origin form posts from other domains you own. Origin checks are exactly what should stop forged requests, so test any legitimate cross-site flows.

### Cache unserialization is hardened

The cache configuration's `serializable_classes` option now defaults to `false`. The upgrade guide says this hardens cache unserialization to help prevent PHP deserialization gadget chain attacks if your application's `APP_KEY` is leaked.

If you cache Eloquent models or other objects, list the classes you actually need there rather than switching the protection off. Leaked keys are not a theoretical concern: researchers found more than 260,000 Laravel `APP_KEY` values in public GitHub repositories. We cover what an attacker can do with one, and how to rotate safely, in [Your Laravel APP_KEY Leaked](/blog/laravel-app-key-leaked).

### Session serialization moves to JSON

New Laravel 13 applications set session `serialization` to `json`. JSON cannot carry PHP objects, which removes a class of unserialization risk from session data.

Existing applications keep their current setting unless you change it, and switching from `php` to `json` logs out every active session. If you store objects in the session, you will need to store arrays or IDs instead.

### Default cookie and cache prefixes change

The fallback values for the session cookie name and cache and Redis prefixes changed from an underscore separator to a hyphen (`_session` to `-session`). If you never set `SESSION_COOKIE`, `CACHE_PREFIX` or `REDIS_PREFIX`, the upgrade renames them. For the session cookie that means everyone is logged out on deploy, and for the cache it means a cold cache.

Set these explicitly in your environment before upgrading. The values below are placeholders:

```bash
SESSION_COOKIE=myapp_session
CACHE_PREFIX=myapp-cache-
REDIS_PREFIX=myapp-database-
```

Use whatever values your application is producing today (check the cookie name in your browser's developer tools), so nothing changes on deploy.

---

## What did not change

A lot of searches ask whether Laravel 13 changed the default database tables. It did not. The default users migration is identical in the Laravel 12 and 13 skeletons and creates the same three tables:

- `users`: id, name, unique email, email_verified_at, password, remember token, timestamps
- `password_reset_tokens`: email (primary key), token, created_at
- `sessions`: id, user_id, ip_address, user_agent, payload, last_activity

The cache and jobs migrations ship in both versions too. If your Laravel 12 application uses the defaults, there is nothing to migrate.

---

## Should you upgrade now?

There is no feature-driven urgency, but there is a deadline. Laravel 12 stopped receiving bug fixes in August 2026 and stops receiving security fixes on **February 24, 2027**. Running a framework with no security support is how a known, published vulnerability ends up being exploitable on your application with nobody to fix it.

A sensible order:

1. Move servers, CI and Docker images to PHP 8.3 or later. This is independent of Laravel and can ship first.
2. Set `SESSION_COOKIE`, `CACHE_PREFIX` and `REDIS_PREFIX` explicitly, and deploy that on Laravel 12.
3. Upgrade `laravel/framework` to `^13.0` with PHPUnit 12 or Pest 4, following the upgrade guide.
4. Review your request forgery exemptions and `serializable_classes`.
5. Decide separately, and deliberately, whether to switch session serialization to JSON.

After deploying, confirm what production actually runs. A [free StackShield scan](/free-scan) checks your live Laravel application from the outside, including exposed debug tools, framework end of life and session cookie flags. The open source [stackshield/scanner](https://github.com/stack-shield/scanner) runs the same kind of checks from inside the app with one artisan command.

---

## Frequently Asked Questions

### What is the difference between Laravel 12 and Laravel 13?

Laravel 13, released March 17, 2026, requires PHP 8.3 or later (Laravel 12 supports PHP 8.2). It adds a first-party AI SDK, JSON:API resources, queue routing by class, more PHP attributes and Cache::touch(). The upgrade changes that matter most are origin-aware CSRF protection (PreventRequestForgery), hardened cache unserialization, JSON session serialization in new apps, and new default cookie and cache prefix names.

### When does Laravel 12 support end?

Laravel 12 bug fixes ended on August 13, 2026. Security fixes continue until February 24, 2027. After that date Laravel 12 receives no patches at all, so plan the upgrade to 13 before then.

### Is Laravel 13 a big upgrade from Laravel 12?

No. The official release notes describe minimal breaking changes, and most applications upgrade in an afternoon. The items to check carefully are the CSRF middleware rename, cache serializable_classes, the session cookie name fallback, and the PHP 8.3 requirement on your servers.

### Did Laravel 13 change the default migrations?

No. The default users migration is identical in the Laravel 12 and 13 application skeletons. It creates the users, password_reset_tokens and sessions tables, with the same columns, and the cache and jobs migrations ship in both versions.

### Will upgrading to Laravel 13 log out my users?

It can. If your session cookie name came from the framework fallback rather than SESSION_COOKIE, the fallback changed from an underscore to a hyphen, which renames the cookie. Switching session serialization from php to json also invalidates existing sessions. Set SESSION_COOKIE explicitly before upgrading to avoid the first one.

