I've optimized a lot of Laravel applications. Here's what actually makes a difference — not the blog-post advice, but the changes with measurable impact.
1. Fix Your N+1 Queries First
This is almost always the biggest win. Install Laravel Debugbar or use DB::listen() to log every query. You'll usually find loops making individual queries.
// Bad — N+1\n$posts = Post::all();\nforeach ($posts as $post) {\n echo $post->author->name; // Query per iteration\n}\n\n// Good — Eager loading\n$posts = Post::with('author')->get();\nforeach ($posts as $post) {\n echo $post->author->name; // No extra query\n}2. Cache Aggressively with Redis
Anything that doesn't change per-user per-request should be cached. Navigation menus, category trees, configuration values — all prime candidates.
$categories = Cache::remember('categories', now()->addHour(), fn() =>\n Category::active()->with('children')->get()\n);3. Use Database Indexes Properly
Run EXPLAIN SELECT on your slow queries. Missing indexes on where, order by, and join columns are extremely common.
// Migration\n$table->index(['tenant_id', 'status', 'created_at']);4. Queue Everything Slow
Email sending, PDF generation, webhook delivery, third-party API calls — if it takes more than 100ms and the user doesn't need the result immediately, queue it.
5. Use Horizon for Queue Monitoring
Laravel Horizon gives you visibility into queue throughput, job runtimes, and failure rates. Essential for production.
Real Results
On a recent e-commerce platform: fixing N+1 queries reduced the product listing page from 4.2s to 380ms. Adding Redis caching for the category tree brought it to 95ms. Small changes, massive impact.