schneems / puma_auto_tune

Puma performance without all the (T)pain
227 stars 19 forks source link

Specify max number of allowed threads? #7

Closed bdmac closed 10 years ago

bdmac commented 10 years ago

The Problem

It seems like puma_auto_tune will lead to problems in an environment like Heroku if you are on a database tier that has a low(ish) number of allowed connections.

The behavior I am seeing upon restarting my app with very low traffic is that puma_auto_tune just keeps growing and growing... I made it up to 9 workers I think before I started bumping into the 512MB dyno limit.

With 9 workers and 16 threads per worker that takes up a theoretical max of 144 database connections. That's for a single web dyno. If you had 2 web dynos or a worker dyno (as we do) you could find yourself in a situation where you're well beyond the cap of 200 connections that many of the lower (even production level) postgres plans come with.

Obviously that's how big the pool is so to actually HIT that you'd have to have a sudden insane flurry of requests but still seems problematic.

Proposed Change

Would it be possible or make sense to allow for setting a maximum thread pool size for a given puma? What I envision is maybe being able to set an ENV var like ENV[MAX_PUMA_THREADS]=64 and then accounting for that in the puma_auto_tune logic when it tries to grow the number of workers. It would have to calculate max threads per puma (hopefully accessible from puma itself) and multiply that by the proposed new number of workers to make sure you are still <= the max threads. In this example, assuming max threads of 16 per worker we'd have a max number of workers of 4.

One could then basically just do the math to figure out what to set the max threads to for puma_auto_tune. E.g.

Database max connections = 200
Desired web dynos = 2
Sidekiq worker concurrency = 25
200 - 25 = 175 connections to play with
175/2 = 87 connections per web dyno

You would then configure via ENV var or otherwise the 
MAX_PUMA_THREADS to 87 which would give you:
Assuming worker max threads = 16 # or whatever you configured
87/16 = 5 max workers per web dyno

It's not ideal but at least I would sleep more soundly knowing that I'm not gonna start hitting DB connection pool timeout errors left and right...

bdmac commented 10 years ago

Alternatively and probably a lot more simply maybe we could just specify an absolute upper bound to how many workers we can grow to?

bdmac commented 10 years ago

Errr... wait a second maybe I'm just really dumb. I thought PumaAutoTune.max_workers was being used internally to track the currently allowed max workers but it looks like maybe it's also settable at config time to give an initial upper bounds < the default of INFINITY...