Is Laravel Slow? Optimize Queries & Indexes for Maximum Performance

July 20, 2025

A detailed, example-rich guide to avoid slowdowns in Laravel apps by optimizing data retrieval and employing indexing smartly.


1. 🧠 Fetch Only What You Need

Loading every column and row with DB::table('users')->get() can clog resources. Instead:

$users = DB::table('users')
    ->select('id', 'name', 'email')
    ->where('status', 'active')
    ->limit(50)
    ->get();
      

With Eloquent:

$users = User::select('id','name','email')
    ->where('status','active')
    ->take(50)
    ->get();
      

Why? Less memory, fewer bytes transferred, faster response times.

2. 🔑 Leverage Database Indexing

If filtering on columns like customer_id or status, adding indexes speeds up searches:

Schema::table('orders', function (Blueprint $table) {
  $table->index('customer_id');
  $table->index(['status', 'created_at']); // composite index
});

Run php artisan migrate to apply. Only add indexes where they help in WHERE, JOIN, or ORDER BY. Avoid over-indexing to prevent slow writes.

3. 🛠️ Profile and Debug Queries

During development:

DB::enableQueryLog();
// run query then:
dd(DB::getQueryLog());

Try tools like Laravel Debugbar or Telescope, or run raw SQL with EXPLAIN to verify index use:

EXPLAIN SELECT * FROM orders WHERE customer_id = 5;

4. ✅ Checklist for Fast Laravel Queries

  • Select only fields you need (select()).
  • Limit rows with limit() or take().
  • Add proper indexes on WHERE/JOIN columns.
  • Profile with Debugbar/Telescope.
  • Avoid loading unused relationships (prevent N+1 queries).

5. ✨ Advanced Tips & Bonus Tricks

Eager vs Lazy Loading: Use with() to avoid N+1:

$posts = Post::with('comments')->get();

Chunking big datasets:

Post::chunk(100, function($posts) {
  foreach ($posts as $post) {
    // process...
  }
});

Cache heavy queries:

$posts = Cache::remember('all_posts', 60, function() {
  return Post::with('comments')->get();
});

Use raw SQL when needed:

$rows = DB::select('SELECT * FROM orders WHERE status = ?', ['active']);

Monitor: Log every query:

DB::listen(function($query){
  Log::info("SQL: {$query->sql} - Bindings: " . implode(',', $query->bindings) . " - Time: {$query->time}ms");
});

6. 🚀 Scale & Optimize Further

  • Enable OPcache in PHP.
  • Use php artisan config:cache and route:cache.
  • Pick fast cache stores (Redis, Memcached).
  • Consider horizontal scaling (multiple servers).
  • Profile regularly; optimize early and often.

By writing precise queries, indexing smartly, and profiling well, your Laravel app will stay fast and scalable. Performance starts at your queries.