When working with large datasets in Rails, loading all records into memory can be expensive and inefficient. That’s where Active Record’s batch processing methods — find_each
and find_in_batches
— come to the rescue. They allow you to iterate over large numbers of records without blowing up your memory usage.
What is find_each
?
find_each is a convenient way to loop over records one at a time, but under the hood it processes them in batches.
1
2
3
User.find_each(batch_size: 1000) do |user|
user.send_weekly_email
end
- Records are fetched in batches of 1,000 by default.
- You get one record at a time in the block.
- Great for operations where you’re performing the same action on each individual record.
What is find_in_batches
?
find_in_batches gives you access to each batch as an array of records, allowing you to process them in groups.
1
2
3
User.find_in_batches(batch_size: 1000) do |users|
users.each { |user| user.send_weekly_email }
end
- You receive a full array of records per batch.
- Ideal when you want to perform operations on the group as a whole — like bulk inserts, CSV exports, or grouped analytics.
When Should You Use Each?
Use find_each
when:
- You’re processing records independently.
- You want clean, simple code.
- You care about memory efficiency per record.
Use find_in_batches
when:
- You need access to the whole batch at once.
- You’re doing grouped logic (e.g. summarizing data).
- You’re optimizing performance with fewer database round-trips.
A Few Things to Keep in Mind
- Both methods do not guarantee order unless you explicitly specify it using
.order(:id)
. - If your records are being updated or deleted during iteration, be careful — batch processing assumes data consistency during the loop.