← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Eager Loading

Performance PHP 5.0+ Intermediate
debt(d5/e3/b5/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list laravel-debugbar, clockwork, and laravel-telescope — these are specialist profiling/debugging tools, not default linters or compiler checks. The N+1 pattern is silent in normal execution but visible when these tools are active, placing it squarely at d5.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is adding ->with(['relation1','relation2']) to an existing Eloquent query — a small, localised change within one query or repository method. It's more than a one-line mechanical swap because you must identify all relationships needed and audit usage, but it doesn't span multiple files structurally, so e3 fits.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). The concept applies_to web, cli, and queue-worker contexts, meaning it's a recurring concern across the full PHP application surface. Every developer working on any data-fetching code must reason about eager vs. lazy loading decisions, and the common_mistakes list shows multiple dimensions of ongoing cost (over-loading, under-loading, nested relationships). It's a persistent tax on many work streams but doesn't fully define the system's shape, so b5.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap — a documented gotcha most devs eventually learn' (t5). The misconception field states explicitly: 'Eager loading is always better than lazy loading' — a common overcorrection once developers learn about N+1. The trap is bidirectional: under-use causes N+1 problems, over-use wastes memory and query time. This is a well-documented gotcha that most developers encounter and learn, fitting t5.

About DEBT scoring →

Also Known As

eager loading ORM with() loading JOIN preloading

TL;DR

Loading related data upfront in a single query rather than deferring until access, preventing N+1 query problems.

Explanation

Eager loading fetches all needed data in one query (or a small fixed number), whereas lazy loading issues additional queries when related data is accessed. In PHP ORMs, eager loading is typically triggered with with() or join() methods. It is the remedy for N+1 query problems: instead of loading 100 posts and then issuing 100 separate queries for each post's author, eager loading fetches all authors in one additional query. The trade-off is fetching data that may not be needed — profile queries to find the right balance.

Common Misconception

Eager loading is always better than lazy loading. Eager loading loads all related data upfront — useful when you know you will need it, wasteful when you load 1000 posts with their authors but only display 5. The right choice depends on access patterns.

Why It Matters

Eager loading fetches related data in a single query upfront — eliminating the N+1 problem where displaying a list of records triggers one query per record for related data.

Common Mistakes

  • Eager loading every relationship by default — loading unused related data wastes memory and query time.
  • Not checking that eager loading is actually used — an eager-loaded relationship that's never accessed is pure waste.
  • Eager loading deeply nested relationships unnecessarily — each level multiplies the data fetched.
  • Using eager loading in APIs where the client only needs IDs — load just what the response requires.

Code Examples

✗ Vulnerable
// Triggers N+1 queries — one per order
$orders = Order::all();
foreach ($orders as $order) {
    echo $order->user->name; // each access fires a new query
}
✓ Fixed
// Eager load — single JOIN query fetches all related records
$orders = Order::with('user')->get();
foreach ($orders as $order) {
    echo $order->user->name; // no additional query
}

// Nested relationships:
$orders = Order::with(['user', 'items.product', 'shipment'])->get();

// Constrained eager loading:
$users = User::with(['orders' => fn($q) => $q->where('status', 'paid')->latest()])->get();

// Check for N+1 in development:
// Laravel Debugbar or:
DB::listen(fn($q) => logger($q->sql)); // logs every query

Added 15 Mar 2026
Edited 22 Mar 2026
Views 50
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 3 pings F 0 pings S 1 ping S 3 pings M 1 ping T 2 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 2 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 11 Perplexity 8 Amazonbot 7 Ahrefs 5 Google 3 Unknown AI 2 Claude 2 Bing 2 ChatGPT 2 Majestic 1 SEMrush 1
crawler 41 crawler_json 3
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Add ->with(['relation1','relation2']) to your Eloquent query or JOIN in raw SQL when you know you'll need related data
📦 Applies To
PHP 5.0+ web cli queue-worker laravel doctrine eloquent
🔗 Prerequisites
🔍 Detection Hints
Loop with $model->relation access without prior ->with() eager load; N+1 shown in Debugbar
Auto-detectable: ✓ Yes laravel-debugbar clockwork laravel-telescope
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update


✓ schema.org compliant