Sitemap
3 min readMar 24, 2025

Preventing Lazy Loading in Laravel: Why and How to Avoid the N+1 Problem

N+1 problem in Laravel queries
n+1 problem

When building Laravel applications, especially large-scale ones with multiple relationships, performance can take a hit due to lazy loading. One of the most common consequences of this is the infamous N+1 problem. If you're not careful, what seems like clean Eloquent code can lead to poor performance and slow response times.

In this post, we’ll explore:

  • What lazy loading is
  • What the N+1 problem looks like
  • Why it’s a problem
  • How to prevent it
  • Laravel features that help you catch it early

What is Lazy Loading in Laravel?

Lazy loading happens when you retrieve a model but don't immediately load its relationships. Laravel will then query the database separately each time you access that relationship.

Example:

$orders= Order::all();
foreach ($orders as $order) {
echo $order->customer->name;
}

In this example, Laravel will:

  • First query all orders
  • Then for each order, run a separate query to get the customer

If you have 100 orders, that's 1 (orders) + 100 (customers) = 101 queries.

Understanding the N+1 Problem

The N+1 problem arises when your application makes one query to get the main records (N), but then makes an additional query for each record's relationship (+1).

Why is it a problem?

  • Database overhead: Hundreds or thousands of queries can significantly increase server load.
  • Slow performance: Increased latency, especially when fetching data for API responses or large dashboards.
  • Scalability issues: As your data grows, performance degrades quickly.

How to Prevent Lazy Loading

1. Use Eager Loading with with()

Laravel allows you to eager load relationships using the with() method.

$orders= Order::with('customer')->get();
foreach ($orders as $order) {
echo $order->customer->name;
}

This generates just 2 queries:

  • One for all orders
  • One for all related customers

2. Use Nested Eager Loading

$orders = Order::with(‘customer.profile’)->get();

This loads customer and their profiles in a single query chain.

Automatically Prevent Lazy Loading (Laravel 9+)

Laravel 9 introduced a new feature to detect and prevent lazy loading during development.

Enable strict mode in AppServiceProvider:

use Illuminate\Database\Eloquent\Model;
public function boot()
{
Model::preventLazyLoading(!app()->isProduction());
}

Now, Laravel will throw an exception when a model tries to lazy load a relationship unexpectedly.

You can also customize this:

Model::preventLazyLoading(true); // Always
Model::preventLazyLoading(false); // Never

Tools to Help

  • Laravel Debugbar: Shows you all queries made during a request, helping detect unnecessary queries.
  • Clockwork: Gives a visual breakdown of your application’s performance, including queries.
  • Laravel Telescope: A Laravel-native debugger that includes query insights.

Bonus Tips

  • Use load() to load relationships after fetching data (not as good as with() but better than lazy loading):

$posts = Post::all();
$posts->load('user');
  • Avoid loading unnecessary relationships — only eager load what you actually use.
  • Index your database columns used in foreign key relationships.

Final Thoughts

Lazy loading can seem convenient, but it hides costly performance issues. Understanding and avoiding the N+1 problem is critical for any Laravel developer aiming to write efficient, scalable applications.

Use eager loading, enable strict mode in development, and monitor your queries. Your application—and your users—will thank you.

No responses yet