Lazy loading helps load related data only when needed. N+1 problem happens when many database queries run unnecessarily. Preventing it makes apps faster and smoother.
Lazy loading and N+1 prevention in Laravel
Model::with('relation')->get();
with() loads related data eagerly to avoid extra queries.
Lazy loading happens automatically when you access a relation property.
$users = User::with('posts')->get();
$posts = Post::all();
foreach ($posts as $post) {
echo $post->user->name;
}$posts = Post::with('user')->get(); foreach ($posts as $post) { echo $post->user->name; }
This code loads all users and their posts in just two queries. It then prints each user and their posts. This avoids the N+1 problem where each user's posts would be loaded separately.
<?php use App\Models\User; // Fetch users with posts eagerly to prevent N+1 $users = User::with('posts')->get(); foreach ($users as $user) { echo "User: {$user->name}\n"; foreach ($user->posts as $post) { echo "- Post: {$post->title}\n"; } }
Use with() to load relations eagerly and avoid many small queries.
Lazy loading is simple but can cause performance issues if not careful.
Check queries in Laravel Debugbar or log to spot N+1 problems.
Lazy loading loads related data only when accessed.
N+1 problem happens when many queries run for related data.
Use with() to load relations eagerly and prevent N+1.
Practice
with() in Laravel Eloquent queries?Solution
Step 1: Understand lazy vs eager loading
Lazy loading delays loading related data until accessed, causing multiple queries (N+1 problem).Step 2: Role of
Thewith()with()method loads related models eagerly in one query, preventing multiple queries.Final Answer:
To load related models eagerly and prevent the N+1 query problem -> Option BQuick Check:
Eager loading =with()usage [OK]
with() to load relations early and avoid many queries [OK]- Confusing lazy loading with eager loading
- Thinking
with()delays loading - Assuming
with()deletes data - Mixing
with()with pagination
Solution
Step 1: Identify Laravel eager loading method
Laravel useswith()to eager load relations, notload()or others in this context.Step 2: Check method chaining and syntax
with('comments')is called beforeget()to eager load comments with posts.Final Answer:
$posts = Post::with('comments')->get(); -> Option AQuick Check:
Eager load syntax =with()beforeget()[OK]
with() before get() for eager loading [OK]- Using
load()statically instead of on model instance - Using non-existent methods like
eager()orfetch() - Calling
with()afterget()
$users = User::all();
foreach ($users as $user) {
echo $user->posts->count();
}
Solution
Step 1: Analyze the initial query
User::all()runs 1 query to get all users.Step 2: Check relation access inside loop
Accessing$user->poststriggers a query per user (lazy loading), causing N additional queries.Final Answer:
N+1 queries, where N is the number of users -> Option AQuick Check:
Lazy loading inside loop = N+1 queries [OK]
with() causes N+1 queries [OK]- Assuming only 1 query runs
- Confusing number of queries with posts count
- Thinking 2 queries run regardless of data size
$orders = Order::with('items');
foreach ($orders as $order) {
echo $order->items->count();
}Solution
Step 1: Check query execution
Order::with('items')builds a query but does not execute it withoutget()or similar.Step 2: Effect on foreach loop
Withoutget(),$ordersis a query builder, not a collection, so foreach will error.Final Answer:
Missingget()afterwith()to execute the query -> Option DQuick Check:
Always callget()to run query afterwith()[OK]
get() after with() to fetch data [OK]- Forgetting to execute query with
get() - Assuming
with()runs query immediately - Confusing relation names without checking model
- Misunderstanding foreach variable naming
Solution
Step 1: Understand nested eager loading
To avoid N+1, load related models and their relations in one query using dot notation.Step 2: Analyze options for efficiency
$authors = Author::with('books.reviews')->get(); useswith('books.reviews')to eager load books and their reviews together, preventing multiple queries.Final Answer:
$authors = Author::with('books.reviews')->get(); -> Option CQuick Check:
Nested eager loading = dot notation inwith()[OK]
with() for nested relations [OK]- Loading relations inside loops causing N+1
- Not eager loading nested relations together
- Using wrong relation names
- Assuming
with('reviews')loads nested reviews
Ready to prove it?
Pass the test and this pattern moves unknown
