php 30 lines · 7 steps

Catching N+1 queries with Eloquent strict mode in Laravel

Configure Eloquent to fail loudly on lazy loading during development while staying quiet in production.

Explained by highlit
1namespace App\Providers;
2 
3use Illuminate\Database\Eloquent\Model;
4use Illuminate\Support\Facades\Log;
5use Illuminate\Support\ServiceProvider;
6 
7class AppServiceProvider extends ServiceProvider
8{
9 public function boot(): void
10 {
11 Model::preventLazyLoading(! $this->app->isProduction());
12 
13 Model::preventSilentlyDiscardingAttributes(! $this->app->isProduction());
14 
15 Model::handleLazyLoadingViolationUsing(function (Model $model, string $relation) {
16 $class = get_class($model);
17 
18 Log::channel('stack')->warning("Lazy loading [{$relation}] on [{$class}].");
19 
20 if ($this->app->runningInConsole()) {
21 return;
22 }
23 
24 throw new \RuntimeException(
25 "Attempted to lazy load [{$relation}] on model [{$class}]. "
26 . 'Eager load it with ->with() to avoid an N+1 query.'
27 );
28 });
29 }
30}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Turning lazy-loading violations into exceptions surfaces N+1 problems at development time instead of in production traffic.
  2. 2Gating strict behaviors on non-production keeps guardrails from breaking live requests.
  3. 3A custom violation handler lets you log context and choose whether to warn or throw per environment.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Catching N+1 queries with Eloquent strict mode in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code