# Should I enable Model::preventLazyLoading only locally or in production too?

> Run it fully strict and throwing in local and CI; in production keep it on but wire handleLazyLoadingViolationUsing to log without failing the request.

- Asked: 2026-07-04
- Answered: 2026-07-07
- Asked by: Ayşe
- Tags: laravel, eloquent, performans
- Source: https://www.muhammetsafak.com.tr/en/just-ask/should-i-enable-model-preventlazyloading-only-locally-or-in-production-too/
- Language: en-US
- Author: Muhammet Şafak

---
**Question:** I'm building an API with Laravel 11 and I want to catch N+1 queries before they reach a release. `Model::preventLazyLoading()` looks like the right tool, but I can't decide exactly where to enable it.

My worry is this: if I turn it on in production, I'm scared it will throw a fatal error (500) at a real user on some code path my tests missed. Should I only enable it locally, or is there a safe way to run it in production too?


Short answer: run it fully strict (throw) in local and CI; keep it on in production, but wire it to a handler that logs instead of throwing. Your worry is valid — flipping raw throwing on cold in prod turns a latent bug into an instant outage.

The trap here is treating this as a binary "local or prod" switch. The version that actually pays off is the same setting behaving differently per environment — loud where a developer can fix it, quiet where a real user would otherwise eat a 500.

1. **Be clear about what it does.** `Model::preventLazyLoading()` throws a `LazyLoadingViolationException` on any lazy-load attempt. Great in development; catastrophic if it returns a 500 to a real user on a path your tests never exercised.
2. **Gate it by environment.** In `AppServiceProvider::boot()`, call `Model::preventLazyLoading(! $this->app->isProduction())`. That makes it strict everywhere except production, where throwing stays off.
3. **In production, log via a handler instead of throwing.** Use `Model::handleLazyLoadingViolationUsing(...)` to report the violation to Sentry/logs with the model + relation name, without crashing the request. You still see the N+1 in production telemetry, but you don't punish the user.
4. **It's one of three strict settings.** It's bundled with `preventSilentlyDiscardingAttributes` and `preventAccessingMissingAttributes` under `Model::shouldBeStrict()`. `shouldBeStrict()` turns all three on at once; enable them deliberately, not blindly. The other two are lower-risk in production, but `preventLazyLoading` is the one that can throw on a real user request, so it earns the separate handler treatment.
5. **It only catches lazy loads, not every N+1.** A query running inside a loop that isn't a relation lazy-load won't trip this mechanism. So you still need Telescope/Clockwork or query-count assertions in your tests.
6. **Roll it out gradually.** Keep production in log-only mode for a few weeks before switching to throwing; promote to throw only after the telemetry is clean, if at all.

```php
// app/Providers/AppServiceProvider.php
public function boot(): void
{
    Model::preventLazyLoading(! $this->app->isProduction());

    Model::handleLazyLoadingViolationUsing(function ($model, $relation) {
        report(new \RuntimeException(
            "Lazy loading detected: ".$model::class."::".$relation
        ));
        // no throw — the request continues its normal flow
    });
}
```

**Bottom line:** personally I'd go fully strict in local + CI, and in production run a log-only handler for the first weeks. Even once telemetry is clean, leaving production on log-only is enough for most teams: you see the N+1s there without hitting anyone with a 500. The real rule: never flip strict throwing on cold in production — measure first, then tighten.

## Related Reading

- [Eloquent Relationships: hasMany, belongsTo, and Eager Loading](/en/blog/eloquent-relationships-hasmany-belongsto-and-eager-loading/) — Blog
- [Should I use chunkById instead of chunk when the same job also updates the rows it iterates?](https://www.muhammetsafak.com.tr/en/just-ask/should-i-use-chunkbyid-instead-of-chunk-when-the-same-job/) — Just Ask
- [Should I bind a Money value object to Eloquent with a custom cast or with accessors/mutators?](https://www.muhammetsafak.com.tr/en/just-ask/should-i-bind-a-money-value-object-to-eloquent-with-a/) — Just Ask
- [How do I stream 2-5 GB file downloads without blowing up PHP's memory?](https://www.muhammetsafak.com.tr/en/just-ask/streaming-multi-gigabyte-file-downloads-without-exhausting-php-memory/) — Just Ask
