Laravel 12

If you’ve been working with Laravel for a while, you’ve probably bumped into the dreaded N+1 query problem. You know the drill: you fetch a bunch of models, then for each model, Laravel fires off extra queries to get related data. Suddenly, your app runs 50 or 100 queries when it really should be doing just a handful. It’s a classic performance bottleneck and a headache to manage.

Well, Laravel 12.8 just made life a whole lot easier with Automatic Eager Loading - a convenient feature that handles this problem for you, quietly and efficiently.

What is the N+1 Query Problem Again?

Imagine you’re building a legal case management platform where you want to display a list of invoices, and for each invoice, show the case and assigned lawyer’s details. Without eager loading, Laravel runs:

For example:

$invoices = Invoice::all(); // 1 query to get all cases

foreach ($invoices as $invoice) {
    echo $invoice->case->id . ' | ' . $invoice->lawyer->name; // Two queries each time this line runs
}

If you have 10 invoices, that is 21 queries. Scale to hundreds of invoices, and your app slows down drastically.

Traditionally, you fix this by telling Laravel exactly which relationships to eager load, like:

$invoices = Invoice::with(['case', 'lawyer'])->get();

Or you would use the load() method like:

$invoices->load([
  'case.client',
  'lawyer',
  'lineItem.service',
]);

But in complex apps with nested or dynamic relationships, keeping track of all the manual loading calls can get tedious and error-prone.

Enter Automatic Eager Loading

Laravel 12.8 introduced a new convenient feature that dynamically detects which nested relations you access and automatically loads them in batches behind the scenes without requiring you to specify them upfront. When you use this feature on a model or collection, Laravel watches your traversal of nested relationships-such as $invoice->client->contact->name, and loads each nested relationship as it is accessed, including multiple levels deep.

You can take advantage of this feature in three ways:

1. Applying it on an Eloquent collection:

$invoices = Invoice::all()->withRelationshipAutoloading();

foreach ($invoices as $invoice) {
    echo $invoice->lawyer->name; // Laravel loads 'lawyer' relationship automatically
}

2. Applying it as the default behaviour of a particular model:


namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Invoice extends Model
{
    protected $autoLoadRelations = true; // Enable automatic eager loading for this model

    public function case()
    {
        return $this->belongsTo(Case::class);
    }
}

3. Apply the behaviour throughout the app globally via the AppServiceProvider:


namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Model;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
      Model::automaticallyEagerLoadRelationships();
    }
}

Behind the scenes, Laravel detects which relationships you actually access and loads them efficiently in the background, significantly reducing the number of queries. So if you access $case->lawyer->firm->address, Laravel will load those related models automatically without you writing a single with() or load() call.

Why This Rocks

Any Downsides?

Since Laravel loads relationships as you access them, memory usage might increase if you’re working with very large collections. But the tradeoff is usually worth it for the massive reduction in query count and cleaner code.

Real Talk: How Much Does It Help?

If you are already trying to avoid N+1 queries, this feature is a more convenient and efficient way of doing so. Instead of manually tracking every possible relationship, Laravel handles it for you, saving time and boosting app speed. If you are new to eager loading, expect up to 60-80% fewer queries in apps with deep, nested relationships.

Wrapping Up

Automatic eager loading in Laravel 12.8 is a subtle but powerful upgrade that lets you write cleaner, more maintainable code while sidestepping one of the most common performance pitfalls in Laravel apps. If you haven’t tried it yet, give it a spin on your next project. Your database (and your users) will thank you!

©2025 Laravel 12