Camkode
Camkode

Supercharge Laravel Performance with withRelationshipAutoloading()

Posted by Kosal

In Laravel 12.8, a powerful new feature landed: withRelationshipAutoloading(). If you've ever battled the N+1 query problem, or tired of manually chaining .load() and .with() all over your models, this new method is about to make your life a lot easier.

This article will break down how withRelationshipAutoloading() works, why it’s useful, and where it fits in your Laravel toolbox.

What is withRelationshipAutoloading()?

Think of withRelationshipAutoloading() as intelligent lazy eager loading.

Normally in Laravel, if you don't specify relationships up front, accessing related data will trigger multiple extra queries—one for each record (the dreaded N+1 problem). Eager loading (with()) fixes that, but it requires you to know exactly which relationships you’ll need in advance.

withRelationshipAutoloading() sits in between:

It allows you to load relationships only when accessed, but does so efficiently by batching queries on-the-fly.

How Does It Work?

Here’s a basic example.

$orders = Order::all()->withRelationshipAutoloading();

foreach ($orders as $order) {
    echo $order->customer->profile->email;
}

You didn’t load customer or profile in advance. But Laravel is smart enough to detect that you’re accessing those relationships, and runs optimized bulk queries behind the scenes.

Instead of making a query per order, it executes:

$orders->loadMissing('customer');
$orders->loadMissing('customer.profile');

All automatically.

More Realistic Use Cases

Nested Relationships in Loops

Let’s say you’re working on a project dashboard:

$projects = Project::all()->withRelationshipAutoloading();

foreach ($projects as $project) {
    echo $project->client->company->name;
    echo $project->posts->first()?->author->name;
}

Without withRelationshipAutoloading(), you’d need something like this:

$projects = Project::with([
    'client.company',
    'posts.author'
])->get();

Not only is that longer, but it also loads relationships even if you don’t end up using them. Wasteful!

Conditional Relationship Access

$tasks = Task::all()->withRelationshipAutoloading();

foreach ($tasks as $task) {
    if ($task->is_completed) {
        echo $task->completedBy->name;
    }
}

You don’t always need completedBy, so eager loading it everywhere would be inefficient. This approach loads only what’s used, when it’s used — without per-record queries.

Enable It Globally (Optional)

Don’t want to call withRelationshipAutoloading() every time? You can turn it on globally:

use Illuminate\Database\Eloquent\Model;

Model::automaticallyEagerLoadRelationships();

Once enabled, all your model collections will batch-load relationships as needed throughout your app.

When Should You Use It?

Use it when:

  • You work with deeply nested or dynamic relationships
  • You’re building dashboards, data pipelines, or admin panels
  • You want to reduce guesswork around eager loading

Avoid it when:

  • You’re working with small datasets (no need to optimize)
  • You don’t know how deeply Laravel will fetch relationships (can cause over-fetching)
  • You need precise control over what data is loaded

Performance Tip: Use Laravel Debugbar

Always profile your queries!

Install Debugbar:

composer require barryvdh/laravel-debugbar --dev

This lets you see exactly which queries Laravel is running, so you can confirm that withRelationshipAutoloading() is doing its job efficiently.

Bonus Example: Combine with Filtering and Pagination

$users = User::where('status', 'active')
    ->withRelationshipAutoloading()
    ->paginate(20);

foreach ($users as $user) {
    echo $user->profile->location;
    echo $user->orders->count();
}

No need to eager load profile or orders explicitly. Laravel will batch load them only when accessed — and only the ones on this page.

Final Thoughts

Laravel’s withRelationshipAutoloading() gives you the best of both worlds:

  • The flexibility of lazy loading
  • The efficiency of eager loading

If your app has grown past a few simple models and you’re constantly juggling which relationships to eager load, this is a must-have feature.

Just don’t forget: power tools are best used carefully. Monitor your queries, test thoroughly, and don’t go overboard.

Summary

Feature Description
with() Manually eager load specific relationships upfront
load() / loadMissing() Load relationships later, usually after fetching data
withRelationshipAutoloading() Automatically detect and batch-load relationships as they’re accessed
automaticallyEagerLoadRelationships() Globally enable relationship autoloading for all models

Want to level up your Laravel skills even more? Follow along for deeper dives into Laravel 12+ features and performance best practices. 🚀