How to configure and pass db connection when using Puma

We have puma configured with 4 workers and min/max threads set to 5. We currently create a rom configuration and cache it in a variable.

module MyPersistance
  extend Dry::Configurable
   def self.configuration
      @configuration ||= do |config|
         config.auto_registration(registration_path, ...)

And do the same for a container.

def self.container
   @container ||= ROM.container(configuration)

Then when instantiating our repositories we pass the container to #new., ...)

This is obviously not thread safe and is causing lots of errors not seen using webrick.
If I remove the caching I get the error “Mysql2::Error: Too many connections”

I have read this post and related issue:

I need some more concrete guidance. What is your recommendation on structuring this correctly to work with puma?

My configuration looks something like this

    # The default options for ROM::Gateway
    def connection_options
        connect_timeout: 2,
        max_connections: @slice.settings.max_threads,
        extensions: %i[connection_validator error_sql pg_array pg_json ksuid]

    # @api private
    def to_gateway
      ROM::Gateway.setup(:sql, to_uri, connection_options)

    # @api private
    def to_config to_gateway).tap do |config|
        config.gateways.each do |(_, gw)|
          gw.connection.pool.connection_validation_timeout = -1

        config.plugin(:sql, relations: :auto_restrictions)

Where @slice.settings.max_threads comes from and env var, and is set in the puma config:

max_threads_count = ENV.fetch("HANAMI_MAX_THREADS", 5)
min_threads_count = ENV.fetch("HANAMI_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

You might need up to 20 connections for 4 workers and 5 threads. If your Configuration connection is over 20, try setting it to be more than 20.

Another possible issue might be that you haven’t properly released the database connection. If this is the case, you might notice many unhandled exceptions.