SYSTEM
Sidekiq¶
Sidekiq is a Ruby background-job framework by Mike Perham (mperham/sidekiq) using Redis as the durable job store. Dominant async-job substrate for Ruby on Rails applications.
Architecture in one paragraph¶
Applications enqueue jobs by calling Worker.perform_async(args)
(or .perform_in / .perform_at for scheduled). The job is
serialised as a hash and pushed to a Redis list under a queue
key. Sidekiq server processes pop from these lists, deserialise,
and invoke Worker#perform in a thread pool. Failed jobs go
through a retry queue with exponential backoff and ultimately a
dead-letter set.
Middleware chains¶
Sidekiq exposes two middleware chains as composition points:
- Client middleware — runs in the calling process at
perform_asynctime, before the job is written to Redis. Receives(worker_class, job_hash, queue, redis_pool). A middleware thatyields passes the job through; one that returnsfalse/nil/ falsy short-circuits the enqueue — nothing ends up in Redis. This is the hook feature-flagged job-enqueue rejection rides on. - Server middleware — runs in the worker process around
perform. Wraps execution; can retry / skip / log / trace.
Both chains are configured in
config/initializers/sidekiq.rb:
Sidekiq.configure_server do |config|
config.client_middleware do |chain|
chain.add(SidekiqMiddleware::SidekiqJobsFlipper)
end
end
Enqueue APIs¶
Worker.perform_async(args)— enqueue immediately. One Redis round-trip per call.Worker.perform_in(delay, args)/.perform_at(time, args)— enqueue with a fixed delay or absolute run-at.Worker.perform_bulk([args1, args2, ...])(Sidekiq 6+) — enqueue N jobs in a single Redis command. The amortisation lever for scheduler bulk-enqueue. PlanetScale uses batches of 1,000.Worker.set(wait: duration).perform_later(args)(ActiveJob) — delayed enqueue, composable with jitter for jittered scheduling.
Sidekiq Enterprise unique jobs¶
Sidekiq Enterprise adds unique_for: + unique_until: worker
options (concepts/sidekiq-unique-jobs):
Framework-level enqueue deduplication: a duplicate
perform_async for the same (class, args) within the
window is rejected silently. Complements application-level
idempotence defences (state re-check, DB locks) as the
third layer of defence against duplicate enqueues —
particularly useful when paired-scheduler architectures
deliberately produce duplicate enqueues.
Retry semantics¶
Default: 25 retries with exponential backoff, jitter, ultimately a dead-letter set. Retry happens on any unhandled exception. Combined with scheduler re-enqueue and user enqueue, this is why idempotent job design is load-bearing — the same logical work can arrive via three independent paths.
Seen in¶
- —
Canonical disclosure of Sidekiq uniqueness as a
webhook-send dedup layer (2023-11-21, Mike Coutermarsh).
PlanetScale runs webhook deliveries as Sidekiq jobs and
reuses Sidekiq Enterprise
unique_for— canonicalised earlier in the 2022-02-17 self-healing-jobs post as a duplicate-enqueue dedup for paired-scheduler architectures — to collapse rapid duplicate webhook enqueues into a single send. Verbatim: "Duplicate webhooks in quick succession get rejected, resulting in only a single unique webhook being sent out from our service, as well as limiting the number of webhooks we need to process." Composes into patterns/defense-in-depth-webhook-abuse-mitigation alongside API rate limits + isolated workers + send timeout + per-DB quota. Also canonicalises Sidekiq as the substrate hosting the isolated Kubernetes webhook worker tier (patterns/isolated-egress-proxy-for-user-urls) whose egress flows through Envoy for SSRF defence. - —
canonical wiki introduction (2022-08-15, Elom
Gomez). PlanetScale's application-tier Rails backend
installs a client middleware that checks per-job-class
Flipper feature flags and
short-circuits enqueue if a
disable_<classname>flag is set. Pattern: patterns/feature-flagged-job-enqueue-rejection. - —
canonical self-healing-architecture disclosure
(2022-02-17, Mike Coutermarsh). Same Rails backend
architected around a
paired
scheduler-reconciler pattern: every job has a
companion scheduler job that runs periodically and
re-enqueues work from authoritative DB state, so
flushing Redis is non-destructive. Introduces the
wiki to Sidekiq's
perform_bulk(batch-of-1,000 amortisation),perform_with_jitter(customApplicationJobhelper for spreading bulk enqueue over a window), and Sidekiq Enterpriseunique_for/unique_untilfor framework-level duplicate rejection. Same post-2022 PlanetScale application tier as the kill-switch post, sibling canonicalisation of the dedup stack.
Related¶
- systems/redis
- systems/ruby-on-rails
- systems/flipper-gem
- concepts/client-middleware-interception
- concepts/idempotent-job-design
- concepts/sidekiq-unique-jobs
- concepts/self-healing-job-queue
- patterns/feature-flagged-job-enqueue-rejection
- patterns/paired-scheduler-reconciler
- patterns/bulk-job-enqueue
- patterns/jittered-job-scheduling
- patterns/isolated-egress-proxy-for-user-urls — Sidekiq hosts the worker tier whose egress flows through Envoy for SSRF defence
- patterns/defense-in-depth-webhook-abuse-mitigation — Sidekiq uniqueness is one of the five amplification defences