I'm having trouble figuring out how exactly concurrency works on Heroku, and how to go about setting the optimal :concurrency
value for Sidekiq
Here's the set up -
Puma Web Server
2 workers
5 threads
Heroku Dynos
8 web dynos
2 "worker" dynos (These will run Sidekiq, not to be confused with Puma Workers)
DB Connections
120 Max Connections Allowed by Postgres
5 Active Record Pool Size (default)
?? Sidekiq :concurrency value
Each Puma worker is allowed the default 5 ActiveRecord DB connections (which corresponds nicely to each having 5 threads). Since there are 2 of these Puma workers per Web Dyno, each Web Dyno consumes up to 10 connections. Across all 8 Web dynos, they take up 80 connections
That leaves 120 - 80 = 40 connections to be used by the 2 dynos that will run Sidekiq. Assuming there's one Sidekiq process running on each dyno (is this true?), each Sidekiq process is free to use up to 20 connections (i.e. set :concurrency 20
)
Is that logic correct, or did I misunderstand how these processes run on dynos?
Is the Sidekiq process limited in any way by the ActiveRecord connection pool limit of 5? If it is, sounds like setting it to 20 is useless since it can really only use a maximum of 5 connections at a time.
Thanks for the help!
Your logic sounds right but a couple of notes.
Puma won't be pushing to Sidekiq on all 5 threads constantly so you can use a lower value, e.g. so the 5 threads share 2 connections:
Sidekiq.configure_client do |config|
config.redis = { size: 2 }
end
Sidekiq concurrency is the number of worker threads, not connections. You want to explicitly limit the connection pool size:
Sidekiq.configure_server do |config|
config.redis = { size: 20 }
end
By default, Sidekiq's connection pool size is (concurrency + 2) but 20 connections should work ok for the default concurrency of 25.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With