[Rails] Configure server workers/threads properly
1. What is Rails Workers/Threads?
Worker
worker is simply a process that runs outside of Rails application request cycle. Each worker is a separate process, it runs its own instance of the Rails application.
Thread
Each worker can run multiple threads to handle multiple requests concurrently within a single process
2. How to configure Rails workers/threads in puma
Normally after you initialize a Rails project, in puma.rb
file you will see this
threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
port ENV.fetch("PORT", 3000)
# Allow puma to be restarted by `bin/rails restart` command.
plugin :tmp_restart
# Specify the PID file. Defaults to tmp/pids/server.pid in development.
# In other environments, only set the PID file if requested.
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
It means:
- worker: not specified in puma file, there is only 1 process by default.
- thread: there are
RAILS_MAX_THREADS
of threads if you specify inside.env
file, if not it is 3 by default.
To configure worker, we need to adjust puma file
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
port ENV.fetch("PORT", 3000)
# Allow puma to be restarted by `bin/rails restart` command.
plugin :tmp_restart
# Specify the PID file. Defaults to tmp/pids/server.pid in development.
# In other environments, only set the PID file if requested.
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
3. How to decide the number of workers/threads properly
How workers/threads affect server performance
Example 1: WEB_CONCURRENCY = 1
and RAILS_MAX_THREADS = 5
we have 1 process with 5 threads, so the application can handle up to 1 x 5 = 5 concurrent requests
If 1 request takes 100ms, the number of Request per second (RPS)
will be
Example 2: WEB_CONCURRENCY = 2
and RAILS_MAX_THREADS = 5
=> Then the application can handle 100 RPS
IF the number of workers/threads is increased, then RPS will be increased?
The answer is: NO => Why? Because: the CPU and Memory of the server is limited. The processes consume server's CPU and memory. If there are more processes and threads, they will consume more CPU and Memory resources.
How to know and choose the perfect number of workers/threads
You need to take a bit of time to do rate test and measure server's CPU & Memory. This is one of the tool to do rate test: Artillery
=> Then based on your server's resources (CPU & Memory) you can define the corresponding numbers of workers/threads => Another way to increase the RPS: optmize our application logic (of course)
End words
I hope I can help you to confidently configure the server properly. What are your thoughts on this approach? Let’s discuss in the comments!
Thanks for reading!
All rights reserved