3 ms·
The discussion in the referenced Rails issue "Set a new default for the Puma thread count"[0] to me is much more telling of IO vs CPU than this simplified post.
by karmakaze 2y ago
The discussion in the referenced Rails issue "Set a new default for the Puma thread count"[0] to me is much more telling of IO vs CPU than this simplified post.
There are many assumptions here especially not considering anything about the database itself. The Rails issue also considers benchmarks which when benchmarking Rails would configure the database to not be the bottleneck. That's not true of real systems. The advice to use async queries for an IO-bound app could backfire if the reason the queries are slow is because the database is overloaded--adding concurrent queries only increases its thrashing and latency.
The best thing to do is consider the whole system. Don't throw the everything that's not the Rails app as IO. Is it actually doing network IO, or is it CPU, memory, or IO bound in the database? Maybe its not even a lack of CPU proper on the database but that it's being wasted on write contention/locks. Only then will you be able to choose the right course. Another way to go is blindly try different configurations and use what works well without full understanding, which is fine until you have an outage you can't explain then scale everything just-in-case.
The ways I've seen this play out:
- small apps (few users) just need good schemas and queries
- medium apps scale(*) webapp instances that solves client CPU & memory and vertically scale single database writer instance
- large apps scale database via sharding or federation/microservices
- other apps may not be able to shard a single tenant so also scale via federation/microservices
(*) Even if webapps are the CPU/memory bottleneck, overscaling them can make the problem of too many connections to the database for long held transactions.
[0] https://github.com/rails/rails/issues/50450 https://github.com/rails/rails/issues/50450