Laravel interview question · Most asked

How do you process a very large table in Laravel without running out of memory?

Summary

Do not use get() or all(). Use chunkById() (batches by primary key), lazyById() (a lazy collection over chunks) or cursor() (one model at a time from a single query), and select only the columns you need.

Longer Answer

  • chunk(1000, fn) uses LIMIT/OFFSET. If you modify rows that affect the query's WHERE clause while iterating, you skip records; offsets also get slower on deep pages.
  • chunkById(1000, fn) paginates with where id > ?, so it is stable while you update rows and fast at any depth. Prefer it.
  • lazy() / lazyById() return a LazyCollection that fetches chunks behind the scenes, so you can write a normal foreach.
  • cursor() runs one query and hydrates one model at a time. Memory for models stays low, but the PDO driver may still buffer the entire result set (MySQL buffers by default), and eager loading is not possible.

For bulk updates, prefer one SQL statement (Order::where(...)->update([...])) over loading models at all. For heavy work, dispatch one queued job per chunk.

Code Example

User::query()
    ->where('newsletter_opt_in', true)
    ->select(['id', 'email'])
    ->chunkById(1000, function ($users) {
        SendNewsletterChunk::dispatch($users->pluck('id')->all());
    });

Key Points

  • chunkById / lazyById over chunk when updating rows.
  • cursor streams models but the driver may buffer.
  • Select only needed columns.
  • Bulk SQL updates beat loading models.

Deep dive: Code Clinic: review a Laravel queue job

Explanation

What interviewers look for

Knowing why chunk can skip rows while updating, and that cursor is not a silver bullet. Strong candidates move heavy work to queued jobs.

Follow-up questions

  • Why can chunk() skip records?
  • How would you export 5 million rows to CSV?

More most-asked Laravel questions

← All Laravel questions