The performance of our applications is one of the top things we should care about. Inefficient Eloquent or DB queries are probably no.1 reason for bad performance. In this tutorial, I will show you the top 3 mistakes developers make when it comes to Eloquent performance, and how to fix them.
Mistake 1: Too Many DB Queries
One of the biggest and most repeating mistakes is the N+1 query issue. This is generally caused by a lot of queries to the database and not using eager loading.
Example 1: Eager Load Relationship
One of the most common example looks like this:
app/Http/Controllers/PostController.php
public function index(){ $posts = Post::all(); return view('posts.index', compact('posts'));}
And imagine you're using the Spatie Media Library package to load media files.
In the Blade file, you would use user and media relationships directly without preloading them:
resources/views/posts/index.blade.php
<ul> @foreach($posts as $post) <li> {{ $post->title }} / By {{ $post->user->name }} @foreach($post->getMedia() as $media) {{ $media->getUrl() }} @endforeach </li> @endforeach</ul>
This produces a result similar to this, which contains a lot of database calls to get related users and media for a post:

To fix this, we can simply modify the controller to eager load the relationship like so:
- Change
all()toget() - Add the
with(['user', 'media'])method to load the relationships
app/Http/Controllers/PostController.php
public function index(){ $posts = Post::with(['user', 'media'])->get(); return view('posts.index', compact('posts'));}
As a result, you will see only 3 queries being executed to load all the required data for the view:

Example 2: Counting Related Models
Another common mistake...
Premium Members Only
This advanced tutorial is available exclusively to Laravel Daily Premium members.
Already a member? Login here
Premium membership includes:
Comments & Discussion
Great article!
Regarding Example 1: with() VS withCount() in Mistake 2
<ul>
@foreach($users as $user)
<li>{{ $user->name }} / Posts {{ $user->posts->count() }}</li>
@endforeach
</ul>
Because we are already eager load the posts for all users, so in the blade view above, laravel will just count it via count() collection method instead of doing the query to database for counting. The only downside of this 'with()' approach is it will take quite much memory which depends on the amount of posts data.
Thanks for this.