Recently, Aaron and I bumped into what we thought was a limitation with eager loading behavior and scoped relationships. Turns out, Laravel was fine. We just had a data issue.
But despite that, both of us still had this nagging memory of something not working quite right with relationships when they were eager loaded, but we couldn't recall the details. So I dug back through my notes and did some source diving into Eloquent's code to refresh my memory.
The issue was limit().
If you wanted to eager load a relationship with a limit, like grabbing the 3 most recent posts per user, the obvious approach would be:
$users = User::with(['posts' => function ($query) {
$query->latest()->limit(3);
}])->get();
For as long as I could remember, that limit(3) applied to the entire eager loading query, not per user.
So you'd get 3 posts total, distributed unpredictably across all your users.
Not 3 per user.
This burned me more than once and got etched into my memory.
But interestingly, when I was trying to reproduce this in my research, it was behaving correctly in Laravel 12!
In fact, when I dug through the history, Laravel fixed this with the release of Laravel 11 and I never noticed. To be fair, it wasn't mentioned in the release notes, and I'm not yet nerdy enough to read every single merged PR description. So my assumptions about Laravel behavior were out of date.
The broader lesson here is worth remembering. Laravel evolves quickly, and something that bit you a while ago, even a behavior that had existed for a decade plus of Laravel's history, might have been quietly fixed since then.
Here to help,
Joel
P.S. Keeping up with Laravel changes is more fun when you have people to discuss them with. Join our community and stay current.