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;
}
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
});
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(),
];
});
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,
],
],
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');
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);
Result: Page response time dropped from 4s to 300ms.
7. Optimize Autoloader with Composer
composer dump-autoload --optimize
composer install --optimize-autoloader --no-dev
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
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
}
});
10. Monitor with Laravel Telescope & Horizon
Install in development to identify bottlenecks:
composer require laravel/telescope --dev
composer require laravel/horizon
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
Top comments (0)