0
0
Laravelframework~15 mins

Eager loading (with) in Laravel - Deep Dive

Choose your learning style9 modes available
Overview - Eager loading (with)
What is it?
Eager loading in Laravel is a way to load related data from the database at the same time as the main data. Instead of loading related data one by one later (which can be slow), eager loading fetches everything in fewer queries. This makes your app faster and more efficient when working with related data.
Why it matters
Without eager loading, your app might make many small database queries, slowing down the user experience and increasing server load. Imagine opening a book and flipping to every page separately instead of reading chapters together. Eager loading solves this by fetching all needed data upfront, making apps feel quicker and smoother.
Where it fits
Before learning eager loading, you should understand Laravel's basic database queries and relationships like hasOne, hasMany, and belongsTo. After mastering eager loading, you can explore advanced query optimization, lazy loading, and database indexing to make your apps even faster.
Mental Model
Core Idea
Eager loading fetches all related data in one go to avoid repeated database queries later.
Think of it like...
It's like buying all ingredients for a recipe in one shopping trip instead of going back to the store multiple times for each item.
Main Data ──► Fetch once
│
├─ Related Data 1
├─ Related Data 2
└─ Related Data 3

All fetched together in one database query batch.
Build-Up - 6 Steps
1
FoundationUnderstanding Laravel Relationships
🤔
Concept: Learn how Laravel connects different data tables using relationships.
Laravel uses relationships like hasOne, hasMany, belongsTo to link tables. For example, a Post hasMany Comments, meaning one post can have many comments. These relationships let you ask Laravel to get related data easily.
Result
You can write code like $post->comments to get comments for a post.
Knowing relationships is essential because eager loading depends on these connections to fetch related data efficiently.
2
FoundationThe Problem with Lazy Loading
🤔
Concept: See why loading related data one by one can slow down apps.
By default, Laravel loads related data only when you ask for it. If you get 10 posts and then ask for comments on each, Laravel runs 1 query for posts plus 10 queries for comments (one per post). This is called the N+1 query problem.
Result
Your app makes many database queries, slowing down response time.
Understanding lazy loading's cost helps you appreciate why eager loading is needed.
3
IntermediateUsing Eager Loading with with() Method
🤔Before reading on: do you think eager loading fetches related data in one query or multiple queries? Commit to your answer.
Concept: Learn how to tell Laravel to load related data upfront using with().
You use with() on your query to load relationships early. For example, Post::with('comments')->get() fetches posts and their comments together. Laravel runs two queries: one for posts and one for all comments related to those posts.
Result
Fewer queries run, improving performance compared to lazy loading.
Knowing how with() works lets you control when related data loads, preventing slowdowns.
4
IntermediateEager Loading Nested Relationships
🤔Before reading on: can you eager load relationships of relationships in Laravel? Commit to yes or no.
Concept: You can load deeper related data by nesting with() calls.
For example, Post::with('comments.user')->get() loads posts, their comments, and the users who wrote those comments. Laravel runs queries for posts, comments, and users all at once.
Result
Complex related data loads efficiently in a few queries.
Understanding nested eager loading helps you fetch complex data structures without performance loss.
5
AdvancedConstrain Eager Loading Queries
🤔Before reading on: do you think you can filter which related records eager loading fetches? Commit to yes or no.
Concept: You can add conditions to eager loading to fetch only certain related records.
Use a closure inside with() to filter. Example: Post::with(['comments' => function($q) { $q->where('approved', true); }])->get() loads only approved comments with posts.
Result
You get only relevant related data, saving memory and time.
Knowing how to constrain eager loading queries lets you optimize data fetching precisely.
6
ExpertEager Loading Performance Internals
🤔Before reading on: does eager loading always reduce queries to one? Commit to yes or no.
Concept: Eager loading runs multiple queries but avoids repeated queries per record by batching.
Laravel runs one query per table involved, not one per record. It then matches related data in memory. This reduces database load but still uses multiple queries for complex relations.
Result
Eager loading balances query count and data volume for best performance.
Understanding this prevents expecting eager loading to always use a single query, avoiding confusion in optimization.
Under the Hood
When you call with(), Laravel builds separate SQL queries for the main model and each related model. It fetches all related records in one go per relationship, then matches them in PHP by foreign keys. This avoids running a query for each individual related record, reducing database round-trips.
Why designed this way?
This design balances complexity and performance. Running one big join query can be slow and return duplicate data. Multiple smaller queries with matching in memory are faster and easier to optimize. Early Laravel versions used lazy loading by default, but eager loading was added to fix the N+1 problem.
┌───────────────┐       ┌───────────────┐
│   Main Query  │──────▶│  Related Data │
│ (Posts table) │       │ (Comments)    │
└───────────────┘       └───────────────┘
         │                      │
         │                      │
         ▼                      ▼
   Fetch posts           Fetch all comments
         │                      │
         └─────────────┬────────┘
                       ▼
               Match comments to posts in memory
Myth Busters - 4 Common Misconceptions
Quick: Does eager loading always run only one database query? Commit to yes or no.
Common Belief:Eager loading runs just one query to get all data.
Tap to reveal reality
Reality:Eager loading runs one query per table involved, not just one query total.
Why it matters:Expecting a single query can lead to confusion when debugging or optimizing performance.
Quick: Can eager loading cause slower performance if used carelessly? Commit to yes or no.
Common Belief:Eager loading always makes your app faster.
Tap to reveal reality
Reality:If you eager load too many or unnecessary relationships, it can fetch too much data and slow down your app.
Why it matters:Blindly eager loading everything wastes memory and bandwidth, hurting performance.
Quick: Does eager loading automatically filter related data? Commit to yes or no.
Common Belief:Eager loading fetches only the related data you want by default.
Tap to reveal reality
Reality:Eager loading fetches all related records unless you explicitly add constraints.
Why it matters:Not filtering related data can cause large, unnecessary data loads.
Quick: Is eager loading the same as joining tables in SQL? Commit to yes or no.
Common Belief:Eager loading is just a SQL join behind the scenes.
Tap to reveal reality
Reality:Eager loading uses separate queries and matches data in PHP, not SQL joins.
Why it matters:Misunderstanding this can lead to inefficient queries or incorrect assumptions about data returned.
Expert Zone
1
Eager loading does not always reduce queries to one; it reduces them to one per relationship, which is often optimal.
2
Using eager loading with large datasets requires careful filtering to avoid loading excessive data into memory.
3
Eager loading can be combined with Laravel's chunking methods to process large data sets efficiently without memory overload.
When NOT to use
Avoid eager loading when you only need a few related records or when the related data is rarely accessed. Instead, use lazy loading or explicit queries to fetch related data on demand to save resources.
Production Patterns
In real apps, developers use eager loading to fix N+1 query problems, often combining it with query constraints and pagination. They also profile queries with Laravel Debugbar or Telescope to decide which relationships to eager load.
Connections
Database Indexing
Eager loading benefits from proper indexing on foreign keys to speed up related data queries.
Knowing how indexes work helps understand why eager loading queries run faster and how to optimize database performance.
Caching
Eager loading reduces database queries, which complements caching strategies to improve app speed.
Understanding caching alongside eager loading helps build highly performant apps by minimizing repeated data fetching.
Batch Processing in Manufacturing
Eager loading is like batch processing where tasks are grouped to reduce setup time and increase efficiency.
Seeing eager loading as batch processing reveals why grouping database queries reduces overhead and speeds up operations.
Common Pitfalls
#1Loading too many relationships without filtering.
Wrong approach:Post::with('comments', 'author', 'tags', 'categories', 'likes')->get();
Correct approach:Post::with(['comments' => fn($q) => $q->where('approved', true), 'author'])->get();
Root cause:Assuming eager loading everything is always good without considering data size or relevance.
#2Expecting eager loading to run only one query total.
Wrong approach:Thinking Post::with('comments')->get() runs one SQL query joining posts and comments.
Correct approach:Understanding it runs two queries: one for posts, one for comments, then matches in PHP.
Root cause:Confusing eager loading with SQL joins.
#3Not eager loading when fetching multiple records with related data.
Wrong approach:$posts = Post::all(); foreach ($posts as $post) { $post->comments; }
Correct approach:$posts = Post::with('comments')->get();
Root cause:Not realizing lazy loading causes many queries (N+1 problem).
Key Takeaways
Eager loading fetches related data in batches to avoid many small database queries, improving app speed.
Use the with() method to specify which relationships to load upfront, including nested relationships.
You can filter eager loaded data to fetch only what you need, saving resources.
Eager loading runs one query per table involved, not just one query total.
Careful use of eager loading prevents common performance problems like the N+1 query issue.