Avoid dogpiling on start/hot restart #3236
-
Starting one puma worker for my Rails app takes 5-7 seconds, and the prod server runs about 20. But if I start (or hot restart) 20 workers at a time, they dogpile the server and all take 90+ seconds to boot, leaving the site down the entire time. I added a slightly janky on_worker_boot that calls So I have the suspicion that I’m going about this entirely the wrong way, but I don’t see another option. Any suggestions? I’d love to PR an addition to the docs to help anyone else with this problem. Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 7 replies
-
Maybe the information that it is (or isn't) a phased restart should be passed on to the hook – feel free to look into this and make PR for it if it is possible :) Makes sense to me. |
Beta Was this translation helpful? Give feedback.
-
In Lines 84 to 86 in 252890c If you add the following after line 85 unless @phased_restart
sleep 0.5 until @workers.last.uptime > 5
@workers.each { |w| w.boot! } # needed to not trigger boot timeout ? fix
end It will stagger worker creation. It needs more code, as it probably interferes with shutting down Puma, checks for whether workers booted, etc. It could be an option like EDIT: I set it to a long time, and requests were responded to. I also sent |
Beta Was this translation helpful? Give feedback.
-
How many CPUs are on this server? I'm wondering why starting X workers at the same time is slower than starting 1. If you have X CPUs or more, this shouldn't be the case. |
Beta Was this translation helpful? Give feedback.
You're creating a footgun though in the case of an overload situation - your Puma processes will ingest more work than you have CPU time to handle, causing requests to get very slow as they wait on the CPU to be available. This creates a difficult situation as your request queue times will not increase (at least not as quickly as they would otherwise), because Puma is still starting to process requests, but processing them slower.
If you're using the threadpool, a 1 to 1 ratio of workers to cpu cores is best.