4 ms·
Beyond application performance, I've also found a non-trivial drag from the complexity of scaling Rails horizontally. Databases need connection pools, which mus
by phamilton 2y ago
Beyond application performance, I've also found a non-trivial drag from the complexity of scaling Rails horizontally. Databases need connection pools, which must be external. Processes vs threads ratio need to be tuned and retuned and the application evolves. Deployments take longer to fully roll out a hundred containers. It's a bunch of tiny bits of complexity that add up.
Moving to a fully concurrent runtime (rust, golang, JVM, beam, etc) suddenly makes so much of that no longer a concern.
- pqdbr 2y agoFor someone that is experienced with Rails but not with the other runtimes mentioned, how do they eliminate the need for db connection pools and speed up deployments across nodes?
- throw_aw100 2y agoI don't have experience with Rails, but I have experience with the other runtimes. I read their comment as needing an external database pool to scale, not that they don't need a pool. When running JVM or the other runtimes, the database pool can be part of the application itself because it uses a different threading model.
- choilive 2y agoRails also has an application level connection pool for the database but as I understand a connection pooler (pgbouncer et al) between PG and the application servers is still necessary when horizontally scaling.
- phamilton 2y agoTo handle 25k qps with Rails, assuming 500ms per request, you need 12k Ruby processes. That probably means you run on 200 boxes with 64 CPUs each. Maybe you get a little bit of oversubscribing of processes to CPUs due to I/O. Conservatively it's still 100 boxes. To handle 25k qps with Rust, you can run 10 boxes. Maybe less. Deployments are complicated (even when we wrap them in simple abstractions). A "rare" delay that impacts 1% of boxes during a deploy will become common on 100 boxes but still somewhat rare on only 10. Running a single rust process per box allows a connection pooler to be in-process. It's more efficient, it supports postgres prepared statements, it's one less operational headache, etc.