While working on the upcoming https://ohdear.app redesign, I noticed that list that displays all sites of a team was very slow. Let's look at a simplified version of how we fetch the data to build the site list for the current team.

When displaying a site list for teams with 200 sites, 200 extra queries are performed, and this is what makes the site list slow.

Here's the modified code: $sites = Team::current() // returns an instance of the team model ->sites() ->with('team') ->get() ->filter(fn (Site $site) => currentUser()->can('administer', $site)); This successfully solves the N+1 problem.

$team = Team::current(); $team ->sites() ->get() ->map(fn (Site $site) => $site->setRelation('team', $team)) ->filter(fn (Site $site) => currentUser()->can('administer', $site)); By using setRelation, Eloquent will not reach out to the database anymore to get the team relation, it will simply return the Team instance we passed.
Newsletter

Get the latest Laravel/PHP jobs, events and curated articles straight to your inbox, once a week

Fathom Analytics | Fast, simple and privacy-focused website analytics. Fathom Analytics | Fast, simple and privacy-focused website analytics.
Community Partners