Reputation: 946
I'm having a hard time to understand the math that I have to do to find out the correct number of RAILS_MAX_THREADS
based on my infrastructure.
I'm using multi containers to host one copy of my API that accepts HTTP requests and one copy of my API that runs sidekiq (job processing). The database that I'm using has a max_connections of 45. With that being said, what should be the number of RAILS_MAX_THREADS
? I'm using 9 for RAILS_MAX_THREADS
AND WEB_CONCURRENCY
. I read a few articles about it but I haven't been able to fully wrap my head around it.
Upvotes: 5
Views: 1641
Reputation: 23317
Heroku's docs on puma sizing are some of the best even if you aren't using heroku.
https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server
Where they say "dyno", you can just read "host", "virtual machine", or "container" for a non-heroku deploy.
If you are using 9 for RAILS_MAX_THREADS
and WEB_CONCURRENCY
, and your heroku config is set to use these settings in the normal way -- then every host will have 9 puma workers running (WEB_CONCURRENCY
), and each worker will be running 9 threads (RAILS_MAX_THREADS
), for a total of 9*9=81 threads.
You really need enough database connections for each thread, so you are already over your 45 database connections by almost 2x. And that's only on ONE container -- if you are running multiple containers, each with these settings, than multiply the 81 by the number of containers -- so that's far too many for your database connections!
So if you are unable to change the max database connections, that is a hard limit and you need to reduce your numbers.
Otherwise, the main limiting factor is how much RAM you have available in each container, and how many vCPUs. Ideally you'd run at least as many workers on a container (WEB_CONCURRENCY
) as you have vCPUs -- if you have enough RAM to do it. Workers take a lot of RAM. There is usually no reason to run MORE workers than vCPUs, so whether 9 makes sense or is larger than needed depends on your infrastructure.
How many threads per worker (RAILS_MAX_THREADS
) is optimal can depend on exactly what your app is doing, but as a good rule of thumb you can start at 5. 9 is probably more than is useful, generally.
So I'd try RAILS_MAX_THREADS
of 3-5. Then as much WEB_CONCURRENCY as you can without running out of RAM (to see how much RAM the app will take after being up under load for a while, you might need to leave it up under load for a while). So long as containers * RAILS_MAX_THREADS * WEB_CONCURRENCY is less than your database max connections -- if it's not, either reduce your values so it is, or increase your database max connections.
Upvotes: 1