Skip to content

Optimum Sidekiq Configuration on Heroku with Puma #12

Description

@winston

What's the optimum config for Sidekiq on Heroku with Puma?

There are quite a number of answers on the Internet, but nothing definitive, and most of them come with vague numbers and suggestions or are outdated.

Basically, these are the questions that are often asked:

  • What do I exactly put in the config/initializers/sidekiq.rb file?
  • What should I set for client/server size?
  • What should I set for client/server concurrency?
  • How does the Puma workers and threads affect the Sidekiq settings?
  • How does the number of Redis connections affect the Sidekiq settings?
  • How does that number of web/worker dynos affect the Sidekiq settings?

The best (and updated) answers I can find are:

With @bryanrite's post as a reference, this is our Sidekiq config:

config/initializers/sidekiq.rb

require'sidekiq_calculations'Sidekiq.configure_clientdo |config|
sidekiq_calculations=SidekiqCalculations.newsidekiq_calculations.raise_error_for_env!config.redis={url: ENV['REDISCLOUD_URL'],size: sidekiq_calculations.client_redis_size}endSidekiq.configure_serverdo |config|
sidekiq_calculations=SidekiqCalculations.newsidekiq_calculations.raise_error_for_env!config.options[:concurrency]=sidekiq_calculations.server_concurrency_sizeconfig.redis={url: ENV['REDISCLOUD_URL']}end

lib/sidekiq_calculations.rb

classSidekiqCalculationsDEFAULT_CLIENT_REDIS_SIZE=2DEFAULT_SERVER_CONCURRENCY=25defraise_error_for_env!returnif !Rails.env.production?web_dynosworker_dynosmax_redis_connectionrescueKeyError,TypeError# Integer(nil) raises TypeErrorraise<<-ERRORSidekiq Server Configuration failed.!!!======> Please add ENV: - NUMBER_OF_WEB_DYNOS - NUMBER_OF_WORKER_DYNOS - MAX_REDIS_CONNECTION ERRORenddefclient_redis_sizereturnDEFAULT_CLIENT_REDIS_SIZEif !Rails.env.production?puma_workers * (puma_threads/2) * web_dynosenddefserver_concurrency_sizereturnDEFAULT_SERVER_CONCURRENCYif !Rails.env.production?(max_redis_connection - client_redis_size - sidekiq_reserved) / worker_dynos / paranoid_divisorendprivatedefweb_dynosInteger(ENV.fetch('NUMBER_OF_WEB_DYNOS'))enddefworker_dynosInteger(ENV.fetch('NUMBER_OF_WORKER_DYNOS'))enddefmax_redis_connectionInteger(ENV.fetch('MAX_REDIS_CONNECTION'))end# ENV used in `config/puma.rb` too.defpuma_workersInteger(ENV.fetch("WEB_CONCURRENCY",2))end# ENV used in `config/puma.rb` too.defpuma_threadsInteger(ENV.fetch("WEB_MAX_THREADS",5))end# https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/redis_connection.rb#L12defsidekiq_reserved5end# This is added to bring down the value of Concurrency# so that there's leeway to growdefparanoid_divisor2endend

The sidekiq_calculations.rb file is dependent on a number of ENV variables to work, so if you do scale your app (web or workers), do remember to update these ENVs:

  • MAX_REDIS_CONNECTION
  • NUMBER_OF_WEB_DYNOS
  • NUMBER_OF_WORKER_DYNOS

At the same time, WEB_CONCURRENCY and WEB_MAX_THREADS should be the identical ENV variables used to set the number of Puma workers and threads in config/initializers/puma.rb.

Our puma.rb looks exactly like what Heroku has proposed.

The only difference to @bryanrite's calculation is that Sidekiq reserves 5 connections instead of 2 now
according to this line, and I have also added a paranoid_divisor to bring down the concurrency number and keep it below a 80% threshold.

Let me know how this config works for you. Would love to hear your feedback!


Thank you for reading.

@winston ✏️ Jolly Good Code

About Jolly Good Code

Jolly Good Code

We specialise in Agile practices and Ruby, and we love contributing to open source.
Speak to us about your next big idea, or check out our projects.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions