Common Eloquent Mistakes That Slow Down Laravel Applications
When building applications with Laravel, Eloquent makes database interactions feel simple and intuitive. However, this convenience can sometimes hide performance issues, especially as your data grows.
Small mistakes like unnecessary queries, loading extra data, or running operations inside loops can significantly slow down your application without you even noticing at first.
This article will show you how to fix common Eloquent mistakes with practical examples. By understanding these patterns, you can write more efficient queries and build applications that scale smoothly.
1. N+1 Query Problem (Most Common Laravel Performance Issue)
Bad
| 1 2 3 4 5 6 7 8 9 10 | $users = User::all(); foreach ($users as $user) { echo $user->posts->count(); } |
Queries executed:
1 query → users
- N queries → posts
If you have 100 users = 101 queries
Good
| 1 2 3 4 5 6 7 8 9 10 | $users = User::with('posts')->get(); foreach ($users as $user) { echo $user->posts->count(); } |
Queries:
1 query → users
1 query → posts
Core Concept
Always ask yourself:
“Will this relationship run inside a loop?”
If yes → use eager loading (with())
2. Using all() When You Don’t Need All Data
Bad
| 1 | $users = User::all(); |
This loads every column and every row.
Good
| 1 | $users = User::select('id', 'name')->get(); |
Why this matters
Large tables may have:
50 columns
500k rows
Loading unnecessary data increases:
• memory usage
• response time
3. Loading Relationships You Don’t Use
Bad
| 1 | User::with(['posts', 'comments', 'roles', 'permissions'])->get(); |
But maybe you only use posts.
Good
| 1 | User::with('posts')->get(); |
Even better:
| 1 2 3 4 5 6 7 | User::with([ 'posts:id,user_id,title', 'posts.comments:id,post_id,body' ])->get(); |
Or
| 1 2 3 4 5 | User::select('id','name','email') ->with('posts:id,user_id,title') ->get(); |
Core Rule
Only eager load what you actually use.
4. Running Queries Inside Loops
Bad
| 1 2 3 4 5 | foreach ($orders as $order) { $user = User::find($order->user_id); } |
This creates many queries.
Good
For less number of records
| 1 2 3 4 5 6 | $userIds = $orders->pluck('user_id'); $users = User::whereIn('id', $userIds)->get(); |
When $userIds contains large number use this :
| 1 | $orders = Order::with('user')->get(); |
5. Counting Using Collections Instead of Database
Bad
| 1 | User::where('active', 1)->get()->count(); |
This loads all users into memory.
Good
| 1 | User::where('active', 1)->count(); |
Core Rule
Let the database do the work, not PHP.
6. Using Eloquent for Heavy Bulk Inserts
Bad
| 1 2 3 4 5 | foreach ($records as $record) { User::create($record); } |
This fires many insert queries.
Good
| 1 | DB::table('users')->insert($records); |
When to avoid Eloquent
For:
• batch imports
• large sync processes
• logs
• analytics data
Use Query Builder.
7. Loading Entire Models for Simple Values
Bad
| 1 2 3 | $user = User::find(1); echo $user->email; |
Good
| 1 | $email = User::where('id', 1)->value('email'); |
Why
This avoids model hydration.
8. Using get() When You Only Need One Record
Bad
| 1 | $user = User::where('email', $email)->get()->first(); |
Good
| 1 | $user = User::where('email', $email)->first(); |
Or even better:
| 1 | $user = User::firstWhere('email', $email); |
9. Not Using Pagination
Bad
| 1 | $users = User::get(); |
On large tables, this can kill memory.
Good
| 1 | $users = User::paginate(50); |
Or for APIs:
| 1 | $users = User::cursorPaginate(50); |
10. Ignoring Chunking for Large Data Processing
Bad
| 1 2 3 4 5 6 7 8 9 10 | $users = User::all(); foreach ($users as $user) { process($user); } |
Memory problem if the table is large.
Good
| 1 2 3 4 5 6 7 8 9 | User::chunk(500, function ($users) { foreach ($users as $user) { process($user); } }); |
11. Use withCount() instead of loading relationships just to count them
Bad
| 1 2 3 4 5 6 | $users = User::with('posts')->get(); echo $user->posts->count(); |
Good
| 1 2 3 4 5 6 | $users = User::withCount('posts')->get(); echo $user->posts_count; |
This avoids loading all posts.
Conclusion
Optimizing Eloquent isn’t about avoiding it; it’s about using it wisely.
By being mindful of how queries are executed, what data is being loaded, and where operations are performed, you can prevent performance bottlenecks early in development. Simple changes like eager loading relationships, selecting only required fields, and leveraging database-level operations can make a significant difference.
As your application grows, these optimizations become even more important. Treat performance as an ongoing practice, not a one-time fix, and you’ll build Laravel applications that remain fast, efficient, and reliable over time.
Recent help desk articles
Greetings! I'm Aneesh Sreedharan, CEO of 2Hats Logic Solutions. At 2Hats Logic Solutions, we are dedicated to providing technical expertise and resolving your concerns in the world of technology. Our blog page serves as a resource where we share insights and experiences, offering valuable perspectives on your queries.

