How do I use Laravel's chunk to avoid running out of memory?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Use Laravel's chunk() to Avoid Running Out of Memory
Dealing with large datasets is a common hurdle in application development, especially when dealing with data migrations, data synchronization, or bulk operations involving thousands or millions of records. As you’ve experienced, fetching 100k+ records into memory all at once—using standard methods like ->get()—is a guaranteed way to trigger PHP's memory limits and cause your application to crash with an Out Of Memory (OOM) error.
The solution lies in processing data iteratively rather than loading the entire result set simultaneously. Laravel provides an elegant, built-in mechanism specifically for this purpose: the chunk() method.
Understanding the Memory Bottleneck
When you execute a query using $class::orderBy('MatrixModifiedDT','desc')->get();, Eloquent fetches all matching records from the database and loads them into PHP memory as an array before returning control to your application. If this array contains 100,000 complex objects, it quickly exhausts available memory, especially when you are performing subsequent processing steps (like iterating and modifying data).
To circumvent this, we need a way to process these 100,000 records in smaller, manageable batches. This is where chunk() comes into play.
What is chunk() and How It Works?
The chunk() method allows you to divide a large result set into smaller pieces (chunks) and iterate over those chunks one by one. Instead of loading everything at once, the database driver streams the results in batches, ensuring that only a small subset of data resides in memory at any given time, thus dramatically reducing memory consumption.
The syntax involves providing two arguments: the chunk size and a callback function that will be executed for each chunk.
As seen in the Laravel documentation, the basic usage looks like this:
User::chunk(200, function ($users) {
// $users will contain at most 200 records at a time
foreach ($users as $user) {
// Process the batch of users here
}
});
In your specific scenario, where you are dealing with potentially large result sets from temporary tables or Eloquent queries, applying chunk() directly to the query ensures that memory pressure is managed throughout the entire operation. This approach aligns perfectly with best practices for efficient data handling in Laravel.
Implementing chunk() in Your Example
Based on your code snippet, the bottleneck occurs when retrieving and processing the $listings. We will apply chunk() directly to this collection to process the listings in batches instead of loading them all at once.
Here is how you can refactor your logic to safely handle large numbers of listings:
use Illuminate\Support\Facades\DB;
// Assuming ListingMigrator and RetsFeed are available
public function fire()
{
// Turn off query logging (good practice for bulk operations)
DB::connection()->disableQueryLog();
$feeds = RetsFeed::where('active', '=', 1)->get();
foreach ($feeds as $feed) {
$class = "TempListing{$feed->board}";
// Instead of getting all listings at once, we use chunk()
$class::orderBy('MatrixModifiedDT', 'desc')
->chunk(5000, function ($listings) use ($feed) { // Process in batches of 5000
foreach ($listings as $listing) {
// Perform the heavy lifting inside the loop
ListingMigrator::migrateListing($listing, $feed);
echo "Feed: {$feed->board}\r\n";
echo "SubcondoName: {$listing->SubCondoName}\r\n";
echo "Development: {$listing->Development}\r\n\r\n";
}
});
}
}
Key Takeaways from the Implementation:
- Batch Size Selection: The first argument (
5000in this example) determines the size of each chunk. You should experiment with this number based on your server's available memory and the complexity of the objects you are processing. A smaller number means less memory used at any instant, but more iteration overhead. - Closure Execution: The closure provided to
chunk()receives an Eloquent Collection (or a standard array, depending on the context) for each batch. You iterate over this batch ($listings) and perform your necessary operations within it. This prevents the entire dataset from ever being loaded into memory simultaneously. - Laravel Efficiency: Utilizing methods like
chunk()showcases how Laravel encourages developers to think about data streaming and resource management, which is fundamental when dealing with large-scale database interactions, as emphasized by principles found on the Laravel Company.
Conclusion
By replacing a single massive .get() call with the memory-efficient chunk() method, you transform an operation that risked crashing your server into a stable, scalable process. For any task involving bulk data migration or processing where record counts are high, adopting chunking is not just a suggestion—it is a mandatory best practice for robust application development. Always prioritize how your application interacts with the database to ensure performance and stability.