Could we help you? Please click the banners. We are young and desperately need the money
Laravel’s Eloquent ORM is powerful and elegant, making it a developer favorite. But with great power comes the risk of performance pitfalls—especially when working with relationships. The most notorious of these is the N+1 query problem, closely followed by query bloat due to careless eager loading or inefficient query building.
In this article, we’ll walk through practical, real-world techniques to identify and eliminate the N+1 problem, optimize your use of with(), and tame bloated queries. Whether you’re a Laravel beginner or an experienced sysadmin managing high-load PHP apps, this post will help you write faster, cleaner, more scalable code.
The N+1 query problem occurs when your application executes 1 query to fetch parent records, followed by N additional queries (one for each parent) to fetch related records. This can quickly become a performance nightmare.
Here’s a classic example:
$posts = Post::all();
foreach ($posts as $post) {
echo $post->user->name;
}
This will result in 1 query for posts + 1 query per post for user — highly inefficient.
These tools highlight how many queries are being executed per request.
Install Debugbar via:
composer require barryvdh/laravel-debugbar --dev
Then refresh your app. If you see hundreds of queries for a single page load, you’ve likely hit the N+1 problem.
Instead of fetching users per post, tell Eloquent to fetch all related users in one go:
$posts = Post::with('user')->get();
foreach ($posts as $post) {
echo $post->user->name;
}
Now, Laravel makes just 2 queries: one for posts, one for users. Problem solved.
You can also eager load nested relationships:
$posts = Post::with('user.profile')->get();
Eager loading is great, but overusing it can result in query bloat—queries becoming unnecessarily complex and pulling excessive data.
If you only need the user’s name:
$posts = Post::with(['user:id,name'])->get();
This reduces overhead by telling Laravel to select only id and name from the users table.
H3: withCount() and withSum()
Instead of counting relationships manually, use:
$posts = Post::withCount('comments')->get();
echo $posts[0]->comments_count;
Or aggregate a column:
$users = User::withSum('orders', 'amount')->get(); echo $users[0]->orders_sum_amount;
For large datasets, consider:
Post::chunk(200, function ($posts) {
foreach ($posts as $post) {
// process post
}
});
Or, with Lazy Collections:
$posts = Post::cursor();
foreach ($posts as $post) {
// process without loading all into memory
}
Install Laravel Debugbar (for local dev):
composer require barryvdh/laravel-debugbar --dev
Mastering Eloquent performance isn’t just for large-scale apps. Whether you’re building a portfolio site or an enterprise API, understanding how to avoid N+1 queries and minimize query bloat is essential.
Always:
By following these patterns, you'll write more efficient, scalable, and production-ready Laravel code.