Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 36 of the Laravel Fundamentals: From Zero to Your First App course
LaravelJune 25, 20264 min read

Querying Related Data: Mastering Eager Loading in Laravel

Stop the N+1 query problem in its tracks. Learn how to use eager loading in Laravel to keep your application fast and efficient as your data grows.

LaravelEloquentPHPWeb DevelopmentPerformancebackend

Previously in this course, we covered the introduction to database relationships in Laravel, where we defined how our User and Task models interact. In this lesson, we are going to move beyond simply defining those relationships and learn how to query them efficiently.

When you start fetching related data, you'll inevitably run into the "N+1" problem. If you’ve ever noticed your application slowing down as you add more records, this is almost certainly the culprit.

The N+1 Query Problem Explained

Imagine you want to display a list of all your tasks, along with the name of the user who created each task. If you do this in a loop, your code might look like this:

PHP
#6A9955">// In your controller
$tasks = Task::all();

#6A9955">// In your Blade view
@foreach ($tasks as $task)
    <p>{{ $task->title }} - Created by: {{ $task->user->name }}</p>
@endforeach

On the surface, this looks correct. However, here is what happens under the hood:

  1. Laravel runs one query to fetch all tasks (SELECT * FROM tasks).
  2. For every single task in that collection, Laravel executes a separate query to fetch the user (SELECT * FROM users WHERE id = ?).

If you have 50 tasks, you are firing 51 queries to the database (1 + 50). This is the N+1 problem. As your application scales, this will destroy your performance.

Solving N+1 with Eager Loading

Eager loading tells Laravel to fetch the related models upfront using a single additional query. Instead of running a query inside the loop, Laravel will perform two queries total: one for the tasks and one for all the users associated with those tasks.

To implement this, we use the with() method in our controller:

PHP
#6A9955">// Optimized controller code
$tasks = Task::with('user')->get();

By adding with('user'), Laravel intelligently gathers all the user_id values from the tasks and executes a single query like SELECT * FROM users WHERE id IN (1, 2, 3...). The performance difference is massive, especially when dealing with hundreds or thousands of records.

Querying Based on Relationships

Sometimes you don't just want to load related data; you want to filter your results based on them. For example, in our Task Manager, you might want to show only tasks that have a specific category or only tasks where the user is an "admin."

We use the has() or whereHas() methods for this.

Using has()

If you want to retrieve only tasks that have at least one comment (assuming you added a comment relationship later):

PHP
$tasks = Task::has('comments')->get();

Using whereHas()

This is more powerful because it allows you to add constraints to the related model. Suppose you want to find all tasks created by users whose name starts with "John":

PHP
$tasks = Task::whereHas('user', function ($query) {
    $query->where('name', 'like', 'John%');
})->get();

This allows you to perform complex filtering without manually joining tables, keeping your code readable and maintainable.

Hands-on Exercise

  1. Open your TasksController in your Task Manager project.
  2. Locate the index method where you currently fetch tasks.
  3. Update the query to eager load the user relationship using Task::with('user')->get().
  4. Open the tasks/index.blade.php file and ensure you are displaying the user's name.
  5. Check your Laravel Debugbar (if installed) or your database logs to verify that the number of queries has dropped significantly.

Common Pitfalls

  • Eager Loading Everything: Don't use with() for every relationship by default. Only load what you actually need in the view. Loading unnecessary data consumes memory and slows down your application.
  • Forgetting the Relationship Name: The string passed to with() must match the exact method name defined in your model. If your method is public function owner(), you must call with('owner'), not with('user').
  • N+1 in API Responses: This problem isn't limited to Blade views. If you are returning JSON from an API, make sure to use with() there as well, otherwise, your JSON serialization will trigger the same N+1 queries.

Recap

We’ve covered the essential tools for working with related data:

  • Eager Loading (with): Use this to prevent the N+1 query problem by batch-fetching relationships.
  • Relationship Querying (whereHas): Use this to filter primary records based on conditions applied to their related models.

By mastering these techniques, you ensure your Task Manager remains performant even as your database grows.

Up next: We will dive into Handling File Uploads to allow users to attach files to their tasks.

Previous lessonIntroduction to Database RelationshipsNext lesson Handling File Uploads
Back to Blog

Similar Posts

LaravelJune 25, 20263 min read

Introduction to Database Relationships in Laravel

Learn how to define hasMany and belongsTo relationships in Laravel. Master Eloquent database relationships to link models and access related data with ease.

Read more
LaravelJune 25, 20263 min read

Introduction to Route Model Binding in Laravel

Stop manually querying the database in your controllers. Learn how route model binding automatically injects Eloquent models into your routes.

Part of the course

Laravel Fundamentals: From Zero to Your First App

beginner · Lesson 36 of 52

  1. 1

    Setting Up the Local Development Environment

    4 min
  2. 2

    Installing Laravel and Exploring Directory Structure

    3 min
  3. 3

    Understanding the .env File and Configuration

    3 min
Read more
LaravelJune 25, 20263 min read

Handling File Uploads: A Laravel Beginner's Guide

Learn how to handle file uploads in Laravel, configure local storage, and manage file paths effectively to store user-provided content in your application.

Read more
  • 4

    The Laravel Application Lifecycle

    4 min
  • 5

    Initializing the Task Manager Project

    3 min
  • 6

    Defining Basic Web Routes

    4 min
  • 7

    Using Route Parameters

    3 min
  • 8

    Creating Your First Controller

    3 min
  • 9

    Returning Responses and Redirects

    3 min
  • 10

    Task Manager: Implementing the Task List Route

    3 min
  • 11

    Introduction to Blade Templating

    3 min
  • 12

    Using Blade Layouts and Sections

    3 min
  • 13

    Implementing Blade Partials

    4 min
  • 14

    Mastering Blade Directives for Loops and Conditionals

    3 min
  • 15

    Task Manager: Building the User Interface

    3 min
  • 16

    Understanding Database Migrations

    3 min
  • 17

    Working with Eloquent Models

    3 min
  • 18

    Performing Basic CRUD Operations

    3 min
  • 19

    Seeding the Database

    3 min
  • 20

    Task Manager: Displaying Real Database Records

    3 min
  • 21

    Capturing User Input from Forms

    4 min
  • 22

    Introduction to Laravel Validation

    3 min
  • 23

    Customizing Validation Error Messages

    3 min
  • 24

    Using Form Requests for Validation

    3 min
  • 25

    Introduction to Authentication

    4 min
  • 26

    Protecting Routes with Middleware

    3 min
  • 27

    Understanding CSRF Protection

    3 min
  • 28

    Preventing Mass Assignment

    3 min
  • 29

    Task Manager: Securing the Application

    3 min
  • 30

    Introduction to Route Model Binding

    3 min
  • 31

    Updating Existing Records

    3 min
  • 32

    Deleting Records

    3 min
  • 33

    Using Named Routes

    3 min
  • 34

    Task Manager: Completing CRUD Functionality

    3 min
  • 35

    Introduction to Database Relationships

    3 min
  • 36

    Querying Related Data

    4 min
  • 37

    Handling File Uploads

    3 min
  • 38

    Using Flash Messages for User Feedback

    3 min
  • 39

    Task Manager: Adding Status and Priorities

    3 min
  • 40

    Introduction to Artisan Commands

    3 min
  • 41

    Debugging with Laravel Tinker

    Coming soon
  • 42

    Understanding Service Providers

    Coming soon
  • 43

    Using View Composers

    Coming soon
  • 44

    Task Manager: Refactoring for Clean Code

    Coming soon
  • 45

    Introduction to Testing

    Coming soon
  • 46

    Testing Forms and Validation

    Coming soon
  • 47

    Using Database Transactions

    Coming soon
  • 48

    Handling Global Exceptions

    Coming soon
  • 49

    Preparing for Production

    Coming soon
  • 50

    Environment Security Best Practices

    Coming soon
  • 51

    Managing Assets in Production

    Coming soon
  • 52

    Task Manager: Deployment Preparation

    Coming soon
  • View full course