The Anatomy of an N+1 Query
When iterating over a collection and calling a relationship method without eager loading, Laravel executes 1 initial query plus N additional queries for each record:
PHP
// Triggers 1 query for projects + 50 queries for tasks!
$projects = Project::all();
foreach ($projects as $project) {
echo $project->tasks->count();
}Solution: Eager Loading with with()
Eager loading reduces 51 queries to just 2:
PHP
$projects = Project::with('tasks')->get();Or when only counting related records without loading model instances:
PHP
$projects = Project::withCount('tasks')->get();Enforcing Strict Mode in Local Development
Prevent N+1 regressions permanently by putting your models into strict mode in AppServiceProvider:
PHP
public function boot(): void
{
Model::preventLazyLoading(! app()->isProduction());
}