Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MouteeSabouni's avatar

Eager Loading

Hey guys, I have a simple question about eager loading that solves the n+1 problem. If I used the with() method to eager load relationships that I'm not even looping through, meaning if I used

$users = User::with('posts')->all()

But didn't use

foreach ($users as $user)
{
    $posts = $user->posts;
}

Would it have any effect on my application performance?

0 likes
16 replies
aleahy's avatar

When you use the with method, it is going to do a database query to load all the information into memory. Eg: Something like select * from posts where user_id in (1, 2, 3, 4, 5, ...) Then it will need to construct the relationships on the model which will also take time and memory.

If you don't need the information, my advice would be don't load it.

But if you had 20 users you wanted to show the posts for, a single query to load those posts will be way more efficient than 20 separate queries to get the posts.

1 like
MouteeSabouni's avatar

@aleahy Thank you for your reply. I understand what you said, and my question was specifically to the line where you said, "If you don't need the information, my advice would be don't load it." Why shouldn't I load it if I'm not using it? Will it make the query that only fetches the users slower, as it will add 'posts' attribute to each user? Again, I'm fully aware of when to use with and how. I just don't know if it will have any side effects on my app if I add it when fetching the users and never use $user->posts.

Snapey's avatar

@Moutee yes, as @aleahy said, it would be a wasted DB query and they are the slowest operations

1 like
aleahy's avatar

@Moutee If you don't need the data, and you load it anyway, then you are slowing down some pages of your app for no reason. DB queries take time. Even if it's only one additional one. You may not notice it when the data is small, but when it is large, it starts becoming a serious problem and your response times will be slow.

I can understand that you just want to have it automatically eager loaded because it just saves you worrying about it. At some point in the future it will probably become a serious problem that will be a pain to fix because you will then have to work out how to only load the data you need in all the places you need it as you undo the auto-eager-loading.

Best to work that way from the start.

1 like
sm3rter's avatar

Yes, it performs an additional query

I can't think of a scenario where I would need to run this code without looping ?!

$users = User::with('posts')->all()
1 like
JussiMannisto's avatar

@sm3rter Because the posts are used somewhere? Of course, there needs to be a loop somewhere because users are in a collection, but it's the same for any collection.

1 like
sm3rter's avatar

@JussiMannisto He mentioned "without looping," which made me curious about why and in what context he would use that approach

2 likes
MouteeSabouni's avatar

@sm3rter Yes, there's no scenario for this on my mind as well. I'm just asking if it would have an effect on my application performance if I used it accidentally.

2 likes
skeith22's avatar

there's an easier way to do this, if by some chance there's some users that you wanted to load their posts

$users = User::all();

foreach ($users as $user) {
    if ($someCondition) { // only load the posts of some users depending on what you what
        $user->load('posts');
    }
}

return $users;

something like this

$users = User::all();

foreach ($users as $user) {
    if ($user->id === 1) { // only load the posts of user id 1
        $user->load('posts');
    }
}

return $users;

This is the best solution you'll need.

1 like
aleahy's avatar

@skeith22 Looping through the users in a foreach is exactly the same as N+1. You are going to do a separate query for each user to load the post.

Yes, your if condition will reduce the number of queries, but using with will mean only 1 query.

1 like
MouteeSabouni's avatar

@skeith22 I understand your approach. If I used the code in your example, I would have one query to fetch all users and one query to fetch the posts of the user with an id of 1, which is ideal. But if I have more than one user within the if condition, then I would run a query for each user to fetch their post(s), which is not actually good. So, we would use the with method here. However, my question was if it would have an effect on my application if I used the method just in case.

1 like
JussiMannisto's avatar

@Moutee It will add another database query, and load all of the posts to memory. What that really means in terms of performance is for you to figure out, since we don't know your app.

But that's beside the point. You shouldn't do unnecessary things "just in case". If you don't use the posts, don't fetch them. If you need them later, then add the with() part. I'm struggling to understand why this is even a consideration.

1 like
skeith22's avatar

@aleahy you're correct, but we don't know what his app really is. I'm just giving him options on what he wants to do with his app.

@mouteesabouni if your application is well optimized like only pulling a few data per page, then it's okay if you're not too concerned about performance. just be aware about it if you're pulling data in the hundreds or thousands, then you're better off with with. then again it depends on where you're gonna used that thing. Also, you can mark it as Best Answer for others if they ran into this as well.

Please or to participate in this conversation.