Large dataset performance
Laravel Feeds is designed to write records incrementally. Memory stays bounded only when the application keeps every upstream step lazy.
Keep the query lazy
Return an Eloquent Builder directly:
public function builder(): Builder
{
return Product::query()
->select(['id', 'title', 'updated_at'])
->where('is_exportable', true);
}
Do not materialize the complete result before generation. Select only required columns and eager-load only relationships used by item() to avoid N+1 queries.
Tune chunk size
The default is 1000 records. Lower values reduce peak model memory and increase query count. Higher values reduce query overhead and increase memory. Measure with production-like row sizes.
public function chunkSize(): int
{
return 500;
}
Split output files
Use perFile() when consumers accept multiple files or one output would become difficult to publish and retry.
public function perFile(): int
{
return 50000;
}
Leave maxFiles() at its default 0 when every matching record must be exported. When both perFile() and maxFiles() are greater than zero, Laravel Feeds exports at most their product and completes successfully without reporting that later records were omitted. Set maxFiles() only when that record cap is intentional.
Queue long-running feeds
Queue mode moves generation out of the console request, but it does not reduce the memory used by a feed. Use an asynchronous connection, run workers with suitable timeout and memory limits, and keep the uniqueness TTL longer than the expected generation time.
Measure the whole path
Measure database time, model hydration, transformation, serialization, and storage publication separately. Remote disks can make publication the dominant cost even when generation is fast.