Sidekiq diagnosis via console: stats, counts, and processes
Sidekiq series — part 2 of 4
- Infra: starting, stopping, killing
- You are here — Diagnosis via console
- Bulk manipulation of jobs and processes
- UI hacks in the dashboard
When something seems off, before deleting or moving jobs, I always do a “read” pass — understand the state before touching anything. This post gathers the read-only commands I use for that step.
General status
1
2
3
4
5
6
7
8
9
10
stats = Sidekiq::Stats.new
stats.processed
stats.failed
stats.scheduled_size
stats.retry_size
stats.dead_size
stats.processes_size
stats.default_queue_latency
stats.workers_size
stats.enqueued
In 5 seconds you know: how many jobs have been processed, how many failed, what’s the size of the retry/dead set, what’s the default queue latency. It’s a mental dashboard without needing the web panel.
Total jobs in a queue by class
1
2
queue_name = 'default'
Sidekiq::Queue.new(queue_name).map { |j| j.klass }.group_by { |e| e }.map { |k, v| [k, v.length] }.to_h
Useful for answering “which worker is dominating this queue?”. When the queue fills up, it’s usually a specific class that’s producing jobs faster than the cluster can consume them.
Total retry jobs by class
1
Sidekiq::RetrySet.new.map { |j| j.klass }.group_by { |e| e }.map { |k, v| [k, v.length] }.to_h
Shows which worker is failing the most. Useful after a deploy: if a new class appears dominating the retry set, it’s a strong indicator of a regression.
Total dead jobs by class
1
Sidekiq::DeadSet.new.map { |j| j.klass }.group_by { |e| e }.map { |k, v| [k, v.length] }.to_h
The dead set is the graveyard: jobs that exhausted all retries. If you see numbers growing here that weren’t expected, it’s worth investigating — you’re literally losing work.
Listing running processes
1
2
3
4
5
ps = Sidekiq::ProcessSet.new
ps.size
ps.each do |process|
p "pid: #{process['pid']} hostname: #{process['hostname']} busy: #{process['busy']} quiet: #{process['quiet']} queues: #{process['queues'].length} [#{process['queues'].sort.join(', ')}]"
end
Shows each live Sidekiq process in the cluster with:
busy— how many threads are working right nowquiet— whether it was paused (not picking up new jobs)queues— which queues this process consumes
In a multi-node cluster, this helps you understand if one of the processes died without notice.
Inspecting workers (active threads right now)
1
2
3
4
5
workers = Sidekiq::Workers.new
workers.size
workers.each do |process_id, thread_id, work|
p "process_id: #{process_id} thread_id: #{thread_id} queue: #{work['queue']} retry: #{work['payload']['retry']} class: #{work['payload']['class']}"
end
Workers is different from ProcessSet: here you see threads executing at this exact moment — what class each one is running, in which queue, whether it’s a retry attempt. Helps you understand what’s stalling when the processed counter stopped rising.
Next in the series
Bulk manipulation of jobs and processes — selecting jobs by class, moving between queues, bulk retry/delete, quieting processes for deploy.