Could we help you? Please click the banners. We are young and desperately need the money
When working with thousands or millions of records in a Laravel application, memory usage can quickly become a bottleneck. Traditional methods like all() or get() eagerly load all data into memory, which can be inefficient or even crash your application.
Laravel’s Lazy Collections, introduced in Laravel 6, offer a smarter way to process large datasets efficiently. Combined with Eloquent’s cursor() method, you can iterate over massive data sets without overwhelming memory.
In this guide, we'll explore how Lazy Collections work, when to use them, and how to integrate them with Eloquent and database queries.
Lazy Collections defer computation until it's needed, using generators under the hood. Unlike traditional collections, Lazy Collections don’t hold everything in memory.
use Illuminate\Support\LazyCollection; LazyCollection::make(function () { for (\$i = 0; \$i < 1000000; \$i++) { yield \$i; } })->take(10)->each(function (\$value) { dump(\$value); });
Even though we define a million elements, only 10 are processed, making it extremely efficient.
The cursor() method returns a Lazy Collection backed by a database cursor:
User::cursor()->each(function (\$user) { // Only one row is loaded into memory at a time echo \$user->email . "\n"; });
Compare this with get():
User::get()->each(...); // 🚨 Loads all records into memory at once
With cursor(), Laravel fetches one row at a time and keeps memory usage stable.
Here’s an example that exports millions of users efficiently:
use Illuminate\Support\Facades\Storage; Storage::put('users.csv', ''); User::cursor()->each(function (\$user) { Storage::append('users.csv', "{\$user->id}, {\$user->email}"); });
This approach prevents memory bloat and scales linearly.
You can use all LazyCollection methods:
$filtered = User::cursor() ->filter(fn(\$user) => \$user->is_active) ->map(fn(\$user) => strtoupper(\$user->email)) ->take(1000); foreach (\$filtered as \$email) { echo \$email . "\n"; }
Don’t use ->count() or ->sum() on a LazyCollection unless you exhaust it (it will iterate all items).
Avoid N+1 queries — still eager load relations when needed:
User::with('roles')->cursor()->each(...);
If sorting is needed, ensure indexes exist on your database columns.
Lazy Collections are a powerful tool in Laravel for handling large datasets. By using cursor() and LazyCollection methods, you can create scalable, memory-safe workflows — whether you’re exporting data, running background jobs, or building CLI tools.
If your app is dealing with large tables, this is a feature you can’t afford to ignore.