Feature request: allow configuring a dedicated Redis per limiter (or group of limiters)
Problem
We're looking for a way to use a dedicated Redis instance for just a handful of limiters.
Our architecture runs multiple self-contained shards of a Rails app to scale horizontally — each shard has its own Rails, Postgres, and Redis, fully isolated:
Shard A: Rails A, Redis A, Postgres A (Customer 1)
Shard B: Rails B, Redis B, Postgres B (Customer 2)
Shard Shared: Redis SharedThere's no communication channel between shards. However, we have a small number of jobs that need to run in parallel across all shards and then synchronize at the end. For that coordination, we need a shared Redis — but only for those specific limiters. Most other limiters should remain isolated per shard.
So this needs to work across shards (each shard limits itself, but shards don't block each other):
Sidekiq::Limiter.concurrent('isolated', 1, wait_timeout: 5, lock_timeout: 30).within_limit do
# different shards can work in parallel, just not within the same shard (standard limiter)
endWhile this needs to be coordinated across shards (no two shards can run it at the same time):
Sidekiq::Limiter.concurrent('parallel', 1, wait_timeout: 5, lock_timeout: 30).within_limit do
# this can't happen in parallel across different shards
endWhat we've tried
Using a single shared Redis for all limiters, and namespacing the isolated ones by shard name:
Sidekiq::Limiter.concurrent('isolated-SHARD-A', 1, wait_timeout: 5, lock_timeout: 30).within_limit do
# different shards can work in parallel, just not within the same shard (standard limiter)
end
Sidekiq::Limiter.concurrent('isolated-SHARD-B', 1, wait_timeout: 5, lock_timeout: 30).within_limit do
# different shards can work in parallel, just not within the same shard (standard limiter)
end
Sidekiq::Limiter.concurrent('parallel-SHARD-SHARED', 1, wait_timeout: 5, lock_timeout: 30).within_limit do
# this can't happen in parallel across shards, uses the shared key
endThis works, but it's error-prone (easy to forget the shard suffix) and routes all shard traffic through a single Redis instance, defeating the purpose of the multi-shard architecture.
We also considered alternatives like other distributed locks (Redlock) or Kafka, but they end up either duplicating functionality or adding more complexity than having native support in the limiter.
Proposed solution
Allow configuring the Redis connection per limiter (or per group of limiters). For example, passing a pool directly:
Sidekiq::Limiter.concurrent('isolated', 1, redis: $contained_shard_redis_pool).within_limit do
# different shards can work in parallel, just not within the same shard (standard limiter)
end
Sidekiq::Limiter.concurrent('parallel', 1, redis: $shared_shard_redis_pool).within_limit do
# this can't happen in parallel across shards
endAlternatively, named Redis pools could be defined in configuration (this might be over-engineering — haven't fully thought it through):
Sidekiq::Limiter.configure do |config|
config.redis = { size: 10, url: 'redis://localhost/15' }
config.redis.shared = { size: 10, url: 'redis://localhost/16' }
end
Sidekiq::Limiter.concurrent('isolated', 1).within_limit do
# implicit, uses default
end
Sidekiq::Limiter.concurrent('parallel', 1, redis: :shared).within_limit do
# uses a specific named pool
endReference: https://github.com/sidekiq/sidekiq/wiki/Ent-Rate-Limiting#redis
Source: sidekiq/sidekiq