Laravel Performance Tuning: A Practical Checklist
A practical Laravel performance checklist: fix N+1 queries, add the right indexes, cache config and routes, queue slow work and measure first.
Most slow Laravel applications I have been asked to look at were not slow because of Laravel. They were slow because of a handful of queries, and the fix took an afternoon once someone measured. This is the order I work through.
1. Measure before changing anything
Install Laravel Telescope or Debugbar in a non-production environment and open the slowest page. Look at two numbers: how many queries ran, and which one took longest. A page running 300 queries has a different problem from a page running one query for three seconds.
2. Remove N+1 queries
The N+1 problem is a loop that runs one query per row. It is the most common cause of slow Eloquent code, and eager loading fixes it.
// 1 query for orders + 1 per order for the customer
$orders = Order::latest()->take(50)->get();
// 2 queries in total
$orders = Order::with('customer')->latest()->take(50)->get();To catch new ones during development, add Model::preventLazyLoading(! app()->isProduction()) to a service provider. Lazy loading then throws an exception instead of quietly running extra queries.
3. Index what you filter and sort by
Run EXPLAIN on the slow query. If it scans the whole table, add an index that matches the WHERE and ORDER BY columns. The details are in my post on MySQL query optimization for reports.
4. Select less
- Select only the columns the page shows, especially when a table has large text columns.
- Paginate. No screen needs ten thousand rows at once.
- Use
chunkByIdorlazyfor exports and batch jobs so memory stays flat.
5. Cache what does not change
In production, run php artisan config:cache, route:cache and view:cache as part of deployment, and make sure OPcache is enabled. For data, cache the results that are expensive and change rarely, such as a product catalogue or a dashboard total, with a clear expiry.
6. Move slow work off the request
Sending email, generating a PDF and calling another system do not need to finish before the user sees a response. Dispatch a job and return. See Laravel queues for business automation for how to make those jobs safe to retry.
What to leave alone
Do not start by swapping the framework, the server or the PHP runtime. Those changes are expensive and usually give less than fixing the three worst queries. Measure, fix the biggest item, and measure again.
Common questions
Why is my Laravel application slow?
The most common causes are N+1 queries, missing database indexes, loading too many rows or columns, and doing slow work such as email or API calls during the request.
How do I find N+1 queries in Laravel?
Use Laravel Telescope or Debugbar to see the query count per page, and enable Model::preventLazyLoading() in development so lazy loading throws an exception.
Which artisan commands improve production performance?
Run php artisan config:cache, route:cache and view:cache during deployment, and make sure PHP OPcache is enabled on the server.