1. What is Eager Loading in Laravel?

By default, Laravel uses lazy loading for relationships. This means:

  • If you fetch a model and then access its related models, Laravel will execute additional queries for each related model.
  • This can cause the N+1 query problem, where N is the number of parent models.

Eager loading solves this by loading related models upfront in the same query, reducing the number of queries.

2. Example Scenario

Suppose we have:

  • User model → has many Post models.
  • Post model → belongs to User.

Models:

// User.php
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}// Post.php
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}

3. Lazy Loading (Default

$users = User::all();

foreach ($users as $user) {
foreach ($user->posts as $post) {
echo $post->title;
}
}

What happens here:

  1. User::all() → 1 query to fetch all users.
  2. $user->posts → For each user, another query is executed to fetch posts.

Problem: If there are 100 users, you will run 1 + 100 = 101 queries.

4. Eager Loading with with

We can use with() to fetch related models in a single query.

$users = User::with('posts')->get();

foreach ($users as $user) {
foreach ($user->posts as $post) {
echo $post->title;
}
}

What happens here:

User::with('posts')->get() → Laravel runs 2 queries:

  • 1 query to get all users
  • 1 query to get all posts for those users

No additional queries in the loop.

This is much more efficient.

5. Eager Loading Multiple Relationships

You can load multiple relationships:

$users = User::with(['posts', 'comments'])->get();
  • Fetch users, posts, and comments in 3 queries, instead of one per relationship per user.

6. Nested Eager Loading

If you want to load relationships of relationships:

$users = User::with('posts.comments')->get();

Laravel will fetch:

  • Users
  • Posts for those users
  • Comments for those posts

7. Conditional Eager Loading

You can also add conditions to eager loading:

$users = User::with(['posts' => function($query) {
$query->where('status', 'published');
}])->get();
  • Only fetch posts with status = published for each user.

8. Lazy Eager Loading

If you already have a collection and want to eager load afterwards:

$users = User::all(); // already fetched

$users->load('posts'); // eager load posts now

9. Select Specific Columns

To optimize, you can select only necessary columns:

$users = User::with('posts:id,title,user_id')->get();
  • Here, id, title, and user_id are fetched for posts instead of all columns.

10. Summary Table

Feature Example Queries
Lazy Loading $user->posts N+1
Eager Loading User::with('posts')->get() 2
Multiple Relationships User::with(['posts', 'comments'])->get() 3
Nested Relationships User::with('posts.comments')->get() 3
Conditional Eager Loading User::with(['posts' => fn($q)=>$q->where('status','published')])->get() 2

Categorized in:

Laravel,