Skip to main content
Back to Blog Database

Database Optimization Techniques for Laravel Applications

Abdelrahman Shrief
Abdelrahman Shrief February 14, 2026
5 min read

Indexing Strategies

Proper indexing is the foundation of database performance. Here's how to identify what to index:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('orders', function (Blueprint $table) {
            // Single column index for frequent lookups
            $table->index('status');

            // Composite index for queries that filter by multiple columns
            $table->index(['user_id', 'status', 'created_at']);

            // Unique index for constraints
            $table->unique(['user_id', 'order_number']);
        });
    }
};

Query Optimization

Use Laravel Debugbar or Telescope to identify slow queries. Common optimizations include:

  • Select only needed columns
  • Use chunking for large datasets
  • Avoid N+1 queries with eager loading
<?php

// Bad - Selects all columns
$users = User::all();

// Good - Select only what you need
$users = User::select(['id', 'name', 'email'])->get();

// Bad - Memory issues with large datasets
$users = User::all();
foreach ($users as $user) {
    $this->processUser($user);
}

// Good - Chunking for large datasets
User::chunk(1000, function ($users) {
    foreach ($users as $user) {
        $this->processUser($user);
    }
});

// Even better - Lazy collections (no memory issues)
User::lazy()->each(function ($user) {
    $this->processUser($user);
});

Redis Caching

Cache frequently accessed data:

<?php

namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\Cache;

class UserService
{
    public function getActiveUsers()
    {
        return Cache::remember('users.active', 3600, function () {
            return User::where('active', true)
                ->with('roles')
                ->get();
        });
    }

    public function getUser(int $id): User
    {
        return Cache::remember("user.{$id}", 3600, function () use ($id) {
            return User::with(['roles', 'permissions'])->findOrFail($id);
        });
    }

    public function updateUser(int $id, array $data): User
    {
        $user = User::findOrFail($id);
        $user->update($data);

        // Invalidate cache
        Cache::forget("user.{$id}");
        Cache::forget('users.active');

        return $user->fresh();
    }
}

Database Query Caching

Cache expensive query results at the query level:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;

class Post extends Model
{
    public static function getPopular(int $limit = 10)
    {
        return Cache::tags(['posts'])->remember(
            "posts.popular.{$limit}",
            now()->addHour(),
            fn () => static::query()
                ->withCount('views')
                ->orderByDesc('views_count')
                ->limit($limit)
                ->get()
        );
    }

    protected static function booted(): void
    {
        static::saved(fn () => Cache::tags(['posts'])->flush());
        static::deleted(fn () => Cache::tags(['posts'])->flush());
    }
}

Conclusion

Database optimization is crucial for application performance. Always profile your queries, use appropriate indexes, and implement caching strategies for frequently accessed data.

Written by Abdo Shrief Senior Laravel Developer based in Cairo.
https://www.abdoshrief.tech

Abdelrahman Shrief
Abdelrahman Shrief Senior Backend Developer

Share this post

Need Help With Your Project?

Let's discuss how I can help bring your ideas to life with expert backend development.

Get in Touch