?? Batch Processing Battle: find_in_batches vs find_each vs in_batches – A Deep Dive for ROR Developers ??
David Raja
Immediate joiner | Ruby on Rails Tech Lead | AWS Certified | Tech Lead and Problem-Solving Enthusiast | Transforming Ideas into Scalable Solutions | Open to New Opportunities
You know the drill. You’ve got a Rails app, and suddenly your database goes from storing your grandma’s cookie recipes to handling millions of user records. ?? You run Model.all thinking, “What could go wrong?”—then your server starts crying. ????
Well, fret not! Rails has some tricks up its sleeve for these massive data operations—find_in_batches, find_each, and in_batches. These are like having pizza cutters for your data slices ??—you’re not gonna eat that pizza whole, right? Same with large datasets! Let’s break it down.
Why Not Model.all?
Before we dive into the heavy stuff, let’s talk about the dreaded Model.all. You know when you call Model.all.map { |p| p.do_something }, it’s like asking Rails to carry all the records from the database into memory. ?? This might be fine if you have 100 records, but if you have a million… well, it’s like trying to carry all your groceries in one trip—don’t. ??
Instead, use batching to break that load into manageable pieces and avoid memory overload. Think of it like cutting up that pizza into slices so you can enjoy it without choking! ?? Let’s look at Rails' magic trio.
1. find_in_batches: The Old Reliable
Let’s start with the OG, find_in_batches. This method is the classic, and it’s been around for a while, silently helping you iterate over large datasets in chunks. It loads records in batches to avoid overloading memory.
How it works:
Project.find_in_batches(batch_size: 500) do |projects|
projects.each { |project| project.do_something_great! }
end
?? Pros:
?? Cons:
Real-world Example: You’ve got 200,000 projects in your database, and you need to send out update emails to your users. You could use find_in_batches to process these in groups of 500:
Project.where(status: 'pending').find_in_batches(batch_size: 500) do |projects|
projects.each { |project| NotificationMailer.update_email(project).deliver_now }
end
No more overload. Your server will thank you. ??
2. find_each: The Sassy Shortcut
If you’re feeling too lazy to write find_in_batches and want something more streamlined, find_each is your go-to. It’s basically find_in_batches, but it handles the looping for you. ??
How it works:
Project.find_each(batch_size: 500) do |project|
project.do_something_great!
end
?? Pros:
?? Cons:
Real-world Example: Got a huge user base and need to mark everyone as "active"? No worries, find_each has your back!
User.find_each(batch_size: 1000) do |user|
user.update(active: true)
end
No hassle, just smooth batch processing. You’re welcome. ??
领英推荐
3. in_batches: The Overachiever
Now, let’s talk about in_batches—this one is the power-user’s best friend. It doesn’t just give you arrays, it hands you full-on ActiveRecord relations. Want to update, delete, or perform some complex operations inside your batches? You got it!
How it works:
Project.in_batches(of: 500) do |batch|
batch.update_all(status: 'completed')
end
?? Pros:
?? Cons:
Real-world Example: Let’s say you’ve got a million orders and you need to mark all those placed on Black Friday as “shipped.” You can easily do that with in_batches:
Order.where(promotion: 'Black Friday').in_batches(of: 1000) do |batch|
batch.update_all(shipped: true)
end
Smooth, efficient, and it won’t kill your server. ??
When Should You Use What?
Why Not Use Model.all?
Here’s why you should steer clear of Model.all on large datasets. Imagine this:
Project.all.map { |p| p.update(status: 'completed') }
You’ve just asked Rails to load every single record into memory. If you’ve got a million records, you’re basically telling your server, “Hey, do you mind carrying this elephant across town? Thanks!” ????
Instead, let’s be smart and use batching methods. Your server will run smoothly, and your users won’t be left staring at a blank screen while the system grinds to a halt. ??
In Conclusion:
Next time you’re dealing with large datasets in Rails, don’t be that developer who crashes the app by loading everything at once. Use batch processing like a pro—whether it’s find_in_batches for simple reads, find_each for automatic looping, or in_batches for full-on ActiveRecord wizardry.
Just remember: With great batches come great responsibility. ??
#RubyOnRails #BatchProcessing #find_each #in_batches #CodingHumor #RailsDev #ROR