Update: The creator of Sidekiq, Mike Perham, quickly and correctly pointed out that standard ActiveRecord use inside Sidekiq should include automatic connection pool checkins when jobs are complete.
I failed to realize that using ActiveRecord::Base.connection checks out a connection from the pool but does not automatically return it at the end of each job / web request. Never fully trusting AR to make the most efficient or performant choices (for our use cases, anyway) when generating SQL, we use this all over the codebase.
The Rails database.yml configuration option
idle_timeout should also probably be reduced from the default of 300 seconds to something more reasonable for your needs. We are starting with 60.
The solution described below remains a solution, but the better long-term fix is to instead use ActiveRecord::Base.with_connection.
If you access your database in non-standard ways inside a Rails app, you must manually release the connection back into the connection pool. This is easily accomplished by calling ActiveRecord::Base.clear_active_connections!().
To make this easy, write a Sidekiq Server Middleware that does it automatically.
class MysqlConnectionPoolMiddleware def call(worker, job, queue) begin ActiveRecord::Base.clear_active_connections!() rescue => e puts(e.message) end begin yield rescue => e puts(e.message) end end end Sidekiq.configure_server do |config| config.server_middleware do |chain| chain.add(MysqlConnectionPoolMiddleware) end end
Place that in
config/initializers/sidekiq.rb and blow a kiss to your database.