10 Laravel Performance Optimization Tips I Learned After 10+ Years in Production

# laravel# performance# php# tutorial
10 Laravel Performance Optimization Tips I Learned After 10+ Years in ProductionFred Castro

After 10+ years building scalable web applications with Laravel for everything from startups to...

After 10+ years building scalable web applications with Laravel for everything from startups to government systems, I've learned that performance optimization isn't about premature optimization—it's about knowing which battles to fight.

Currently leading development for a federal government system (CAPES), I've had to optimize Laravel apps handling thousands of concurrent users. Here are the 10 most impactful performance tips I wish I knew when I started.

1. Eager Loading: Stop the N+1 Query Monster

The #1 performance killer I see in Laravel codebases:

// BAD: N+1 queries
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->user->name; // Query fired for EACH post
}

// GOOD: 2 queries total
$posts = Post::with('user')->get();
foreach ($posts as $post) {
    echo $post->user->name;
}
Enter fullscreen mode Exit fullscreen mode

Impact: Reduced query count from 1,001 to 2 queries in a real project.

2. Database Indexing: The Silent Performance Booster

Add indexes to columns you filter/join on:

Schema::table('posts', function (Blueprint $table) {
    $table->index('user_id');
    $table->index('status');
    $table->index(['category_id', 'published_at']); // Composite index
});
Enter fullscreen mode Exit fullscreen mode

Pro tip: Use EXPLAIN in MySQL to identify missing indexes.

3. Cache Expensive Operations

// Cache database queries
$users = Cache::remember('active_users', 3600, function () {
    return User::where('active', true)->get();
});

// Cache computed values
$stats = Cache::remember('dashboard_stats', 600, function () {
    return [
        'total_users' => User::count(),
        'active_sessions' => Session::where('active', true)->count(),
    ];
});
Enter fullscreen mode Exit fullscreen mode

In production: This reduced our dashboard load time from 2.3s to 180ms.

4. Use Redis for Sessions and Cache

// config/database.php
'redis' => [
    'client' => 'phpredis', // Use phpredis extension, not predis
    'cluster' => false,
    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],
],
Enter fullscreen mode Exit fullscreen mode

Why Redis? Memory-based storage = 10-100x faster than database sessions.

5. Optimize Eloquent: Select Only What You Need

// BAD: Fetches all columns
$users = User::all();

// GOOD: Select specific columns
$users = User::select('id', 'name', 'email')->get();

// EVEN BETTER: Use pluck for single column
$emails = User::pluck('email');
Enter fullscreen mode Exit fullscreen mode

6. Queue Heavy Operations

Don't make users wait for emails, notifications, or file processing:

// Dispatch to queue
ProcessVideoUpload::dispatch($video);
SendWelcomeEmail::dispatch($user);

// Chain jobs
ProcessOrder::withChain([
    new SendInvoice($order),
    new UpdateInventory($order),
])->dispatch($order);
Enter fullscreen mode Exit fullscreen mode

Result: Page response time dropped from 4s to 300ms.

7. Optimize Autoloader with Composer

composer dump-autoload --optimize
composer install --optimize-autoloader --no-dev
Enter fullscreen mode Exit fullscreen mode

In production: Always run with optimization flags.

8. Enable OPcache in Production

; php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0 # Disable in production
opcache.revalidate_freq=0
Enter fullscreen mode Exit fullscreen mode

Impact: 30-50% performance boost for free.

9. Use Chunk for Large Datasets

// BAD: Loads 100k records into memory
User::where('active', true)->get()->each(function ($user) {
    // Process user
});

// GOOD: Process in chunks
User::where('active', true)->chunk(200, function ($users) {
    foreach ($users as $user) {
        // Process user
    }
});
Enter fullscreen mode Exit fullscreen mode

10. Monitor with Laravel Telescope & Horizon

Install in development to identify bottlenecks:

composer require laravel/telescope --dev
composer require laravel/horizon
Enter fullscreen mode Exit fullscreen mode

Telescope shows you:

  • Slow queries
  • Memory usage
  • Request duration
  • N+1 query problems

Bonus: Production Checklist

  • Enable OPcache
  • Use Redis for cache/sessions
  • Run php artisan config:cache
  • Run php artisan route:cache
  • Run php artisan view:cache
  • Use CDN for assets
  • Enable GZIP compression
  • Database connection pooling

My Stack for High-Performance Laravel Apps

After years of optimization, here's what I recommend:

  • Web Server: Nginx + PHP-FPM
  • Cache: Redis (with phpredis extension)
  • Database: PostgreSQL with proper indexes
  • Queue: Redis or RabbitMQ for complex workflows
  • Monitoring: Laravel Telescope + Horizon + New Relic

Wrapping Up

Performance optimization is a journey, not a destination. Start with the low-hanging fruit (eager loading, indexing, caching) and measure the impact.

In my work on the CAPES federal system, these optimizations reduced response times from 3-5 seconds to under 200ms, handling thousands of concurrent users smoothly.

What's your #1 Laravel performance tip? Drop it in the comments!


Building scalable Laravel apps for 10+ years | Currently: Senior PHP/Laravel Developer at CAPES | Available for consulting and architecture reviews