Stop N+1 Queries: Enforce Laravel Strict Mode

The Silent Database Killer
When engineering B2B SaaS platforms at Smart Tech Devs, the most common database performance killer is the dreaded N+1 Query Problem. It happens when developers fetch a list of records and then loop through them to access a relationship that hasn't been eager-loaded.
Imagine displaying 50 invoices on a dashboard, and looping through them to print the client's company name: $invoice->client->name. If you forgot to append ->with('client') to your initial query, Eloquent will execute 1 query to fetch the invoices, and then 50 separate queries to fetch each individual client. In a local development environment, these 51 queries execute in 10 milliseconds and go completely unnoticed. In production, under heavy traffic, this N+1 avalanche instantly exhausts your database connection pool and brings the server to its knees.
The Enterprise Solution: Proactive Enforcement
You cannot rely entirely on code reviews to catch missing eager loads. The architectural solution is to configure the framework to physically prevent developers from writing N+1 queries in the first place.
Laravel provides a powerful architectural guardrail called Strict Mode. By enforcing Model::preventLazyLoading() at the application level, Laravel will actively monitor your database relationships. If the framework detects a lazy load (an N+1 query) during local development or testing, it throws a fatal LazyLoadingViolationException, breaking the page and forcing the developer to fix the code immediately.
Step 1: Architecting the Guardrail
We configure this safety mechanism globally inside the AppServiceProvider. Crucially, we only throw fatal exceptions in our local and testing environments. If a rogue N+1 query somehow slips into production, we gracefully log it rather than crashing the user's dashboard.
namespace App\Providers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
// 1. Prevent N+1 Queries
// Throws an exception in dev/testing, but logs gracefully in production
Model::preventLazyLoading(! app()->isProduction());
// 2. Prevent Silent Mass Assignment Failures
// Throws an exception if a developer tries to save a column
// that isn't defined in the model's $fillable array.
Model::preventSilentlyDiscardingAttributes(! app()->isProduction());
// 3. Prevent Memory Leaks on Missing Relationships
// Prevents $invoice->client->name from returning null if the client was deleted,
// enforcing strict data integrity checks.
Model::preventAccessingMissingAttributes(! app()->isProduction());
}
}
Step 2: Graceful Production Logging
To ensure we maintain visibility in production without breaking the app, we can customize how Laravel handles these violations by registering a custom handler.
use Illuminate\Database\Eloquent\Model;
public function boot(): void
{
Model::handleLazyLoadingViolationUsing(function (\(model, \)relation) {
\(class = get_class(\)model);
// Push this directly to a dedicated Slack or Discord telemetry channel
\Log::warning("N+1 Query Detected in Production: Attempted to lazy load [{\(relation}] on model [{\)class}].");
});
}
The Engineering ROI
By enforcing Strict Mode in your application provider, you shift database optimization to the very left of your development pipeline. N+1 queries become impossible to merge. Your codebase becomes inherently highly optimized, ensuring that your production PostgreSQL databases only ever receive clean, batched, and eager-loaded queries.




