A Sidekiq queue can be full while the system is healthy. It can also look almost empty while users wait far too long for important work.

Queue size is inventory. Queue latency is waiting time. Job runtime is service time. They influence each other, but they answer different questions. Treating them as one metric is how teams end up adding workers to a database bottleneck or deleting retries that were exposing a failing dependency.

This article is for Rails teams investigating delayed background work. It is not a capacity formula or a substitute for observing your own jobs, Redis, database and downstream services.

Start with the user-visible deadline

Before opening a Sidekiq dashboard, define what is late.

An email that may arrive within ten minutes has a different service expectation from a payment confirmation, an import status update or a webhook that unblocks another system. Record:

  • the job class and queue;
  • when the job was enqueued;
  • when execution started;
  • when it finished or failed;
  • the deadline the product actually requires;
  • whether a user or another system is waiting.

Without that boundary, “the queue is slow” is not a diagnosis. A five-minute latency may be harmless for a nightly export and unacceptable for a security notification.

Queue latency measures waiting, not execution

Sidekiq defines queue latency from the age of the oldest job waiting in a queue. It helps answer: how long has work been waiting before a processor can begin it?

That is different from job runtime. A job can wait for one second and then run for twenty minutes. Another can wait for twenty minutes and finish in fifty milliseconds. Both feel delayed, but the interventions are different.

Track at least:

  • queue latency by queue;
  • enqueued job count;
  • jobs enqueued per unit of time;
  • jobs completed per unit of time;
  • runtime distribution by job class;
  • success, failure, retry and dead-job counts;
  • worker-process availability and busy threads.

A single aggregate across every queue can hide the failure. A large low-priority export queue may dominate the count while a small critical queue misses its deadline.

Read latency together with arrival and completion rates

A rising latency trend means waiting work is getting older. It does not tell you why.

Compare the rate at which jobs arrive with the rate at which they complete:

  • Arrival rises, completion remains stable. Demand changed or an upstream producer is creating more work.
  • Arrival is stable, completion falls. Workers, database, Redis or another dependency may be slower or unavailable.
  • Both rise, latency stays bounded. The system may be scaling normally.
  • Queue count falls but latency remains high. A small number of old, blocked or repeatedly failing jobs may remain.
  • Latency oscillates on a schedule. Batch jobs or synchronized producers may be creating periodic bursts.

Use a time window that includes the incident. A current dashboard after the queue has recovered cannot explain what happened earlier.

Check runtime before increasing concurrency

If jobs take longer, the same worker capacity completes fewer jobs. Find out whether runtime changed before raising Sidekiq concurrency.

Inspect job classes separately. Look for:

  • larger input data or batch size;
  • N+1 queries or expensive database plans;
  • database connection waiting;
  • lock contention;
  • slower external APIs;
  • missing or ineffective timeouts;
  • file conversion, image processing or other CPU-heavy work;
  • memory pressure and garbage collection;
  • a deployment near the first runtime change.

More Sidekiq threads can increase throughput only when dependencies can support them. If every job needs a database connection, concurrency beyond the usable connection pool creates waiting rather than capacity. If the bottleneck is one downstream API, additional workers may amplify rate-limit failures.

Write down the constraint you expect a concurrency change to relieve. Then measure that constraint during a bounded rollout.

Separate Redis health from application throughput

Sidekiq uses Redis for its job data. Redis availability and command latency matter, but a healthy Redis instance does not mean jobs are completing on time.

Check:

  • Redis command latency and errors;
  • network connectivity from worker processes;
  • memory policy and available memory;
  • whether application caching and Sidekiq share resources in a way that creates contention;
  • connection-pool exhaustion;
  • deploys or infrastructure events affecting workers.

Avoid running broad, expensive Redis commands against production merely to investigate a queue. Use Sidekiq's supported monitoring surfaces and targeted operational metrics.

Retries are pressure and evidence

A retry is not just another failed job. It is future work scheduled to re-enter the system. When a dependency fails, a retry wave can keep pressure high after the original incident has ended.

Group retries by job class and exception. Ask:

  • Is the error transient?
  • Is retrying safe and idempotent?
  • Does the retry repeat an external side effect?
  • Is one malformed input guaranteed to fail again?
  • Is a downstream outage causing many jobs to retry together?
  • Does the product expose pending, failed and manual-recovery states honestly?

Do not clear the retry set just to make a graph look better. Preserve enough evidence to understand the failure and decide whether jobs should retry, be fixed and replayed, or move to a manual recovery path.

Verify queue isolation and priority

Sidekiq queues let you separate classes of work, but queue configuration is also an operational policy.

A critical job can still wait behind bulk work if:

  • both use the same queue;
  • worker processes do not consume the critical queue as expected;
  • strict ordering or weights do not match the intended priority;
  • the critical queue has too little dedicated capacity;
  • a deployment changed process configuration;
  • a queue name changed between producer and worker.

Document which processes consume each queue. Confirm the live configuration rather than assuming it matches a checked-in file.

Use isolation deliberately. Creating a queue for every job class makes operations harder without necessarily protecting any deadline.

Build an incident timeline

For a useful diagnosis, align these events on one timeline:

  1. queue latency and depth;
  2. enqueue and completion rates;
  3. job runtimes and exceptions;
  4. retry volume;
  5. worker restarts and busy-thread count;
  6. database connections, locks and query latency;
  7. Redis latency and errors;
  8. downstream response time and rate limits;
  9. deploys, batch schedules and traffic changes.

The timeline helps separate cause from reaction. High database utilization may have slowed jobs, or a sudden worker expansion may have caused the database utilization.

Change one capacity boundary at a time

Possible interventions include:

  • fixing a slow query or N+1 path;
  • reducing job payload or batch size;
  • adding a timeout and bounded failure policy;
  • making a job idempotent before replay;
  • isolating deadline-sensitive work;
  • smoothing a batch producer;
  • adjusting worker processes or concurrency;
  • increasing database or downstream capacity;
  • adding backpressure at the producer.

Do not combine all of them into one emergency configuration change if you can avoid it. You need to know which change improved the system and which new risk it introduced.

For each rollout, record:

Evidence Before After Acceptance boundary
Queue latency
Enqueue rate
Completion rate
Job runtime p95
Retry rate
Database wait
Downstream errors

The table is blank because borrowed numbers are not evidence for your system.

What the first investigation should produce

A bounded Sidekiq investigation should leave the team with:

  • the affected queue and product deadline;
  • a timeline of latency, arrivals, completions and failures;
  • the job classes responsible for most waiting or runtime;
  • the strongest supported bottleneck hypothesis;
  • retry and idempotency risks;
  • one or more reversible interventions;
  • rollout, monitoring and rollback criteria.

Queue latency is a useful signal. It becomes a diagnosis only when you connect it to the work entering the system, the resources completing it and the deadline users depend on.

If delayed jobs are one symptom of a wider production problem, see how we diagnose systems before changing capacity. You can also send us the queue, deadline and incident context for a focused technical conversation.

Sources

Checked 13 August 2026: