Introduction:
When applications grow in size or handle large volumes of data, optimization techniques become essential, not only to prevent bugs but also to enhance the overall user experience.
Laravel is a powerful and opinionated framework that can deliver high-performance applications when paired with professional optimization strategies.
In this post, we’ll explore practical tips and techniques to optimize your Laravel applications and make them more efficient and scalable.
1. Database query optimization:
- 1.1. Eager Loading:
Eager loading come to fix the N+1 query problem, so what is this problem ?
The code below shows how we iterate in each book to get the author.
// app/Models/Book.php:
class Book extends Model
{
public function author()
{
return $this->belongsTo(Author::class);
}
}
// Then, in some Controller:
$books = Book::all();
foreach ($books as $book) {
echo $book->author;
}
so we have one query for books and N queries for each author
Instead of , now we apply the eager load using ::with
// Instead of:
$books = Book::all();
// You should do:
$books = Book::with('author')->get();
The difference is clear
- 1.2. Select only needed columns select()
:
It is all about Avoiding the transfer of unecessary data, below a good example which use select()
combined with Eager Loading
.
<?php
use App\Models\Post;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
$posts = Post::with('user:id,name')
->select('id','user_id','title')
->get();
return view('posts', ['posts' => $posts]);
});
- 1.3. Handle large datasets safely and memory-efficiently chunkById()
:
It’s explicitly designed for large datasets and production-scale apps, chunkById()
prevents Laravel from loading everything into memory at once.
$posts = Post::all(); //too slow in large data sets
Instead use this
$posts = collect();
Post::chunkById(1000, function ($collection) use (&$posts) {
$posts->push(...$collection);
}, 'id');
- 1.4. Use query builder for raw data instead of Eloquent models toBase()
:
when You are fetching large volumes of row and you can reduce memory usage by skipping model hydration, or in case your API returns plain objects or arrays.
$users = User::where('active', 1)->get();
// Each $user is a full Eloquent model
$users = User::where('active', 1)->toBase()->get();
// Each $user is a stdClass with only selected fields
⚠️Don't use it when :
you need Eloquent relationships
you're using accessors/mutators
you rely on model events or casts
2. Laravel Caching:
Optimization isn't only about efficient queries and database structure , let's explore Laravel Caching.
Caching is a powerful performance booster that avoids repeated DB hits or expensive logic.
-Expensive queries : query caching
In this example posts will be in cache for 60 s and no need for frequent queries
Cache::remember('posts', 60, fn() => Post::all());
-Response caching:
Used for Static or slow-changing pages, you can spatie/laravel-responsecache
as example
-Config/view caching:
Used on deployment for faster boot , you can use php artisan config:cache
, view:cache
3. Rate Limiting:
Important for API protection and stability — avoids abuse and load spikes, especially important in public APIs or high-traffic apps
*Laravel uses RateLimiter middleware
*Can define custom rules per user, IP, role:
RateLimiter::for('api', fn (Request $request) =>
Limit::perMinute(60)->by($request->ip())
);
4. Database Indexing:
Beyond Laravel itself — indexing is a core SQL optimization.
Laravel migrations support indexes:
$table->index('user_id');
$table->unique(['email']);
$table->fullText('title');
5. Eloquent Performance Tips:
-Avoid loading unused relationship, i.e Use withOnly()
in Laravel 11.
-Use pluck()
instead of get()
when only values are needed
Prefer raw queries DB::select
for heavy logic where Eloquent overhead is too much.
6. Job Queues & Background Processing:
Move heavy work (emails, exports, 3rd-party APIs..) to background queues.
Use Laravel queues: dispatch(new ExportJob())
;
Process with workers: Redis + Supervisor (or Laravel Octane for high concurrency).
Conclusion:
Laravel optimization depends not only on efficient queries and database structure but also on caching, indexing, rate limiting, and code-level best practices like chunking and eager loading. Using Laravel’s built-in tools smartly — along with SQL tuning and caching layers — can significantly improve performance and scalability.
Thank you so much for explaining eager loading and chunkById() so clearly! Your code examples made it easy for me to understand how to efficiently handle large datasets in Laravel and avoid the N+1 query issue. This is just what I needed for improving my app’s performance!