DEV Community

Cover image for Laravel 13 drops March 17 — here's every new feature with code examples
K. Polash
K. Polash

Posted on

Laravel 13 drops March 17 — here's every new feature with code examples

Laravel 13 is 9 days away. Taylor Otwell announced it at Laracon EU 2026 and the headline is: zero breaking changes. Smoothest upgrade in Laravel's history.

Here's everything that's changing, with before/after code for the features that actually matter day-to-day.


PHP 8.3 is now the minimum

First the housekeeping. Laravel 13 drops PHP 8.2 support. Check your version:

php -v
Enter fullscreen mode Exit fullscreen mode

If you're on 8.2, upgrade your server before upgrading Laravel. Everything else in this list is non-breaking and optional.


1. PHP Attributes — the headline feature

This is the one everyone will be talking about. Instead of declaring model config, job settings, and command signatures as class properties, you can now use native PHP #[Attribute] syntax.

Models — before:

class Invoice extends Model
{
    protected $table = 'invoices';
    protected $primaryKey = 'invoice_id';
    protected $keyType = 'string';
    public $incrementing = false;
    protected $fillable = ['amount', 'status', 'user_id'];
    protected $hidden = ['internal_notes'];

    // actual model logic starts way down here...
}
Enter fullscreen mode Exit fullscreen mode

Models — after:

#[Table('invoices', key: 'invoice_id', keyType: 'string', incrementing: false)]
#[Fillable('amount', 'status', 'user_id')]
#[Hidden('internal_notes')]
class Invoice extends Model
{
    // your real logic is immediately visible
}
Enter fullscreen mode Exit fullscreen mode

Jobs — before:

class ProcessPayment implements ShouldQueue
{
    public $connection = 'redis';
    public $queue = 'payments';
    public $tries = 3;
    public $timeout = 60;
}
Enter fullscreen mode Exit fullscreen mode

Jobs — after:

#[WithQueue(connection: 'redis', queue: 'payments', tries: 3, timeout: 60)]
class ProcessPayment implements ShouldQueue
{
    // queue config declared, not buried
}
Enter fullscreen mode Exit fullscreen mode

Commands — before:

class SendReportCommand extends Command
{
    protected $signature = 'report:send {--force}';
    protected $description = 'Send the weekly report email';
}
Enter fullscreen mode Exit fullscreen mode

Commands — after:

#[Command(signature: 'report:send {--force}', description: 'Send the weekly report email')]
class SendReportCommand extends Command
{
}
Enter fullscreen mode Exit fullscreen mode

This also works on listeners, notifications, mailables, broadcast events, requests — around 15 locations total. And again: fully optional. Your existing code works exactly as before.


2. Cache::touch() — extend TTL without re-fetching

This one's been a quiet performance footgun for years. To extend a cache item's expiry you had to fetch the value, then re-store it:

// Before — 2 round trips, full payload transfer
$value = Cache::get('user_session:123');
Cache::put('user_session:123', $value, now()->addHour());
Enter fullscreen mode Exit fullscreen mode

Laravel 13:

// After — single EXPIRE command to Redis
Cache::touch('user_session:123', 3600);
Enter fullscreen mode Exit fullscreen mode

Under the hood: Redis gets one EXPIRE command. Memcached uses native TOUCH. Database driver runs a single UPDATE. No value retrieval, no payload transfer.

If you're extending TTLs on every request at scale (sliding sessions, rate limit windows, subscription checks) — this adds up fast.


3. Reverb database driver — real-time without Redis

Scaling Laravel Reverb horizontally previously required Redis. Laravel 13 adds a database driver so you can use MySQL or PostgreSQL instead:

'reverb' => [
    'scaling' => [
        'driver' => 'database', // new — no Redis required
    ],
],
Enter fullscreen mode Exit fullscreen mode

For small-to-medium projects that don't want to provision a separate Redis instance just for WebSockets, this is a big deal.


4. Passkey authentication

Passkeys (WebAuthn — Face ID, fingerprint, hardware keys) are now built into Laravel's starter kits and Fortify. No third-party packages. Scaffolded automatically on new Laravel 13 apps.


5. Laravel AI SDK goes stable

The Laravel AI SDK exits beta on March 17 alongside Laravel 13. First-class LLM integration (OpenAI, Anthropic, others) with proper queue support and Laravel-native conventions.


6. Teams support returns to starter kits

Jetstream had Teams. The newer starter kits didn't. Laravel 13 brings it back with a cleaner implementation.


Other improvements worth knowing

  • MySQL DELETE…JOIN now correctly applies ORDER BY and LIMIT — previously silently ignored
  • HTTP pool concurrency defaults to 2 instead of null — pooled requests are now actually concurrent out of the box
  • Symfony 7.4 and 8.0 support

How to upgrade

"require": {
    "php": "^8.3",
    "laravel/framework": "^13.0"
}
Enter fullscreen mode Exit fullscreen mode
composer update
php artisan config:clear
php artisan cache:clear
php artisan view:clear
Enter fullscreen mode Exit fullscreen mode

Make sure PHP 8.3 is running first. Test on staging before touching production.


Full feature breakdown

I wrote a more detailed version with upgrade notes and FAQ on my blog:

👉 Laravel 13 New Features: Everything You Need to Know


Which feature are you most excited about? PHP Attributes are the headline but I think Cache::touch() is the one that will quietly save the most performance at scale. Drop your thoughts below.

Top comments (0)