> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sidekiq

export const VersionRequirements = ({versions = []}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const boundaries = {
    upper: " or lower",
    exact: "",
    lower: " or higher"
  };
  const containerStyle = {
    marginTop: "0.5rem",
    marginBottom: "1.5rem"
  };
  const lineStyle = {
    display: "block",
    margin: "0 0 0.35rem 0",
    fontSize: "0.875rem",
    lineHeight: "1.4"
  };
  const pillBaseStyle = {
    display: "inline-block",
    padding: "0.1em 0.4em",
    borderRadius: "0.25rem",
    border: "1px solid",
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
    fontSize: "0.85em",
    fontWeight: 500
  };
  const pillColors = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#e9d5ff",
      color: "#9333ea"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#99f6e4",
      color: "#0d9488"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#bbf7d0",
      color: "#16a34a"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#bfdbfe",
      color: "#2563eb"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fecaca",
      color: "#dc2626"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fed7aa",
      color: "#ea580c"
    }
  };
  const defaultPillColor = {
    background: "#f4f4f5",
    borderColor: "#e4e4e7",
    color: "#52525b"
  };
  const getPillStyle = name => ({
    ...pillBaseStyle,
    ...pillColors[name] || defaultPillColor
  });
  const getBoundText = bound => {
    return boundaries[bound] || boundaries.lower;
  };
  return <div style={containerStyle}>
      {versions.map((v, i) => <p key={`${v.name}-${v.version}-${v.bound || "lower"}-${i}`} style={lineStyle}>
          This feature requires{" "}
          <code style={getPillStyle(v.name)}>{v.name}</code> version {v.version}
          {getBoundText(v.bound)}.
        </p>)}
    </div>;
};

export const Compatibility = ({versions = [], label = "Available in"}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const defaultPillStyle = {
    borderColor: "#d4d4d8",
    background: "#f4f4f5",
    color: "#3f3f46"
  };
  const pillStyles = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#d8b4fe",
      color: "#6b21a8"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#5eead4",
      color: "#115e59"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#86efac",
      color: "#166534"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#93c5fd",
      color: "#1e40af"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fca5a5",
      color: "#991b1b"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fdba74",
      color: "#9a3412"
    }
  };
  const getPillStyle = name => ({
    ...defaultPillStyle,
    ...pillStyles[name] || ({})
  });
  return <div className="not-prose my-4 rounded-lg border border-zinc-200 bg-zinc-50 px-4 py-3 text-sm dark:border-white/10 dark:bg-white/5">
      <div className="flex flex-wrap items-center gap-x-2 gap-y-1">
        <span className="font-semibold text-zinc-700 dark:text-zinc-200">
          {label}:
        </span>
        {versions.map((v, i) => <span key={`${v.name}-${v.version}-${i}`} className="inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium" style={getPillStyle(v.name)}>
            <span>{v.name}</span>
            <span className="opacity-70">
              {v.version}
              {v.exact ? "" : "+"}
            </span>
          </span>)}
      </div>
    </div>;
};

<VersionRequirements
  versions={[
{ name: "AppSignal for Ruby", version: "2.11.0" }
]}
/>

[Sidekiq](http://sidekiq.org) is a simple and efficient background processor for Ruby. It's also the processor we use to process jobs in AppSignal.

When AppSignal detects Sidekiq metrics, it will create an [Magic Dashboard](#magic-dashboard), allowing you to monitor core metrics visually.

## Sidekiq monitoring for Ruby on Rails apps

The AppSignal Ruby gem automatically inserts a listener into the Sidekiq server middleware stack if the `Sidekiq` module is present if you use Rails. No further action is required.

The Sidekiq integration is compatible with [Active Job](/ruby/integrations/active-job).

## Sidekiq monitoring for Ruby apps

Adding this config should only be necessary when Sidekiq doesn't automatically load AppSignal through the app's framework, like Rails.

Add this snippet to your Sidekiq config with the right environment and name:

<CodeGroup>
  ```ruby Ruby theme={null}
  require 'appsignal'

  Sidekiq.configure_server do |config|
    config.on(:startup) do
      # Start AppSignal
      Appsignal.start
    end

    config.on(:shutdown) do
      # Stop the agent
      Appsignal.stop('Sidekiq shutdown')
    end
  end
  ```
</CodeGroup>

## Performance monitoring

Once AppSignal begins reporting Sidekiq metrics, AppSignal will give you performance insights via:

* [Event timeline](#event-timeline)
* [Error tracking](#error-tracking)
* [Incident grouping](#incident-grouping)
* [Sample breakdown](#sample-breakdown)

### Event timeline

`perform_job.sidekiq` events will be shown in the event timeline on the performance incident detail page:

<img src="https://mintcdn.com/appsignal-715f5a51/MS9b5WO71lSfD5jG/assets/images/screenshots/ruby/integrations/sidekiq/event-timeline.png?fit=max&auto=format&n=MS9b5WO71lSfD5jG&q=85&s=8fc45ec517eeb7571491aef0f81ca6fe" alt="Example event timeline" width="1314" height="488" data-path="assets/images/screenshots/ruby/integrations/sidekiq/event-timeline.png" />

### Error tracking

Track exceptions that occur when running Sidekiq jobs.

When Sidekiq encounters a problem before or after a job has been processed, such as parsing JSON from Redis, it will raise an error. This error is reported under the SidekiqInternal action on the background namespace, as the job context is unknown when the error occurs.

<img src="https://mintcdn.com/appsignal-715f5a51/MS9b5WO71lSfD5jG/assets/images/screenshots/ruby/integrations/sidekiq/error.png?fit=max&auto=format&n=MS9b5WO71lSfD5jG&q=85&s=1b07bec6ca219e7c991108eda21173eb" alt="Example sidekiq error" width="1310" height="482" data-path="assets/images/screenshots/ruby/integrations/sidekiq/error.png" />

#### Report errors on job discard

<Compatibility
  versions={[
{ name: "AppSignal for Ruby", version: "3.9.0" },
{ name: "Sidekiq", version: "5.1.0" },
]}
/>

Set the [`sidekiq_report_errors` config option](/ruby/configuration/options#option-sidekiq_report_errors) to `discard` to only report errors when a job is discarded. When a job is discarded, all job retries have been exhausted, and the job is no longer retried. Read the [Sidekiq documentation](https://github.com/sidekiq/sidekiq/wiki/Error-Handling) to learn more about Sidekiq exception handling and failed job retries.

<Warning>
  When using Sidekiq with Active Job's retry system, configure it [to report
  errors only on
  discard](/ruby/integrations/active-job#report-errors-on-job-discard), so
  that it won't report errors multiple times.

  After the Active Job retries are exhausted, the Sidekiq retry system will
  take over. Disable the Sidekiq retry system if this is unwanted behavior.
</Warning>

### Incident grouping

Job names are automatically detected based on the Sidekiq worker class name and suffixed with the `perform` method name, resulting in something like: `MyWorker#perform`.

<img src="https://mintcdn.com/appsignal-715f5a51/MS9b5WO71lSfD5jG/assets/images/screenshots/ruby/integrations/sidekiq/job-performance-samples.png?fit=max&auto=format&n=MS9b5WO71lSfD5jG&q=85&s=dadb8d091a692cc8b45c9a003d639a9e" alt="Example performance incident grouping" width="983" height="362" data-path="assets/images/screenshots/ruby/integrations/sidekiq/job-performance-samples.png" />

### Sample performance

Sample breakdowns allow you to review Sidekiq's performance quickly and spot performance problems without having to dive deep into the details.

<img src="https://mintcdn.com/appsignal-715f5a51/MS9b5WO71lSfD5jG/assets/images/screenshots/ruby/integrations/sidekiq/sample-breakdown.png?fit=max&auto=format&n=MS9b5WO71lSfD5jG&q=85&s=916a9579cc0f297c62ff6100be90c5db" alt="Example Sidekiq performance sample" width="1310" height="436" data-path="assets/images/screenshots/ruby/integrations/sidekiq/sample-breakdown.png" />

## Magic dashboard

When AppSignal receives Sidekiq metrics, it will create a Sidekiq magic dashboard, available from the dashboard section of the AppSignal app.

The Sidekiq magic dashboard will have the following graphs:

| Graph                                                  | Metrics                                                            | Tags                                  |
| ------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------- |
| [Connection count](#connection-count-graph)            | `sidekiq_connection_count`                                         | `hostname`                            |
| [Duration per worker](#duration-per-worker-graph)      | `transaction_duration`                                             | <li>`action`</li><li>`namespace`</li> |
| [Job status per queue](#job-status-per-queue-graph)    | `sidekiq_queue_job_count`                                          | <li>`status`</li><li>`queue`</li>     |
| [Overall job status](#overall-job-status-graph)        | `sidekiq_job_count`                                                | <li>`status`</li><li>`hostname`</li>  |
| [Queue latency](#queue-latency-graph)                  | `sidekiq_queue_latency`                                            | <li>`hostname`</li><li>`queue`</li>   |
| [Queue length](#queue-length-graph)                    | `sidekiq_queue_length`                                             | <li>`hostname`</li><li>`queue`</li>   |
| [Redis memory usage](#redis-memory-usage-graph)        | <li>`sidekiq_memory_usage`</li><li>`sidekiq_memory_usage_rss`</li> | `hostname`                            |
| [Throughput per worker](#throughput-per-worker-graph)  | `transaction_duration`                                             | <li>`action`</li><li>`namespace`</li> |
| [Worker/processes count](#workerprocesses-count-graph) | <li>`sidekiq_worker_count`</li><li>`sidekiq_process_count`</li>    | `hostname`                            |

Tags give you a contextual breakdown of Sidekiq performance information. AppSignal reports the following tags for Sidekiq jobs:

| Name        | Description                                                                                                       |
| ----------- | ----------------------------------------------------------------------------------------------------------------- |
| `action`    | The name of the action the metric was reported from (e.g., `YourWorker#perform`).                                 |
| `hostname`  | The name of the host the metric was reported from.                                                                |
| `namespace` | The name of the namespace the metric was reported from.                                                           |
| `queue`     | Named queue in which jobs are processed, e.g. `default` or `mailer`.                                              |
| `status`    | Status of each job, either `processed` or `failed`. <br />Jobs that are `failed` are also counted as `processed`. |

Each tag will be represented with a colored line on the graph:

<img src="https://mintcdn.com/appsignal-715f5a51/4TRZP0Sq9Zq7PAPW/assets/images/screenshots/ruby/integrations/sidekiq/dashboard.png?fit=max&auto=format&n=4TRZP0Sq9Zq7PAPW&q=85&s=142e1a00e315e511d35fb80892957e22" alt="Example Sidekiq dashboard" width="1432" height="672" data-path="assets/images/screenshots/ruby/integrations/sidekiq/dashboard.png" />

### Connection count graph

The Connection count graph shows the count of Sidekiq connections per host.

You can use the Connection count graph to monitor Sidekiq connections per host, spot connection trends and bottlenecks, and optimize resources.

### Duration per worker graph

The Duration per worker graph shows the amount of time that it took for jobs to execute, grouped by namespace and action.

You can use the Duration per worker graph to monitor the performance of workers per action and namespace, giving you a helicopter view of Sidekiq performance and allowing you to quickly identify and investigate spikes in duration time.

### Job status per queue graph

The job status per queue with a priority graph shows the number of jobs that were executed, grouped by their resulting status, by the queue in which they were queued.

You can use the Job status per queue graph to monitor job error counts and performance based on queue, identify bottlenecks, and optimize your background jobs for scalability.

### Overall job status graph

The overall job status graph shows the number of expected Sidekiq jobs per status and namespace.

You can use the Overall job status graph to monitor failed jobs and track job distribution across namespaces.

### Queue latency graph

The Queue latency graph shows the latency the queue experienced at the time of measurement. [Sidekiq calculates this](https://github.com/mperham/sidekiq/wiki/API) by subtracting the time the last job was enqueued from the time of measurement. This value is reported as milliseconds.

You can use the Queue latency graph to spot delays in processing jobs, detect queue congestion, and understand how quickly background jobs start.

### Queue length graph

The Queue length graph shows the length of Sidekiq queues per queue and namespace.

You can use the Queue length graph to monitor queue performance and spot and solve Sidekiq bottlenecks.

### Redis memory usage graph

The Redis memory usage graph shows:

* The Virtual Memory Size memory usage of Redis (`sidekiq_memory_usage_rss`)
* The Resident Set Size memory usage of Redis (`sidekiq_memory_usage_rss`)

You can use the Redis memory usage graph to monitor Sidekiq's memory usage, improve resource management, and optimize memory-intensive jobs.

### Throughput per worker graph

The Throughput per worker graph shows the number of jobs that were executed, grouped by hostname.

You can use this graph to monitor worker performance, grouped by the class that defines the job.

### Worker/processes count graph

The Worker/processes count graph shows the number of Sidekiq workers and executed processes.

You can use the Worker/processes count graph to manage workload distribution, optimize resource allocation, and identify performance problems.

## Hostname configuration

AppSignal attempts to detect the hostname of the Redis instance your Sidekiq instance uses to store its queues. If the detection is not accurate, it's possible to customize the hostname configuration by overriding the default Sidekiq probe.

First, you'll need to [override the default Sidekiq probe](/ruby/instrumentation/minutely-probes#overriding-default-probes) by registering a new probe with the same name (`:sidekiq`). This probe will need a configuration hash, including the `:hostname` key, with the new hostname value. By specifying the `:hostname` config option in the Sidekiq minutely probe, the metrics will be tagged with the given hostname value. The `:hostname` config option value is not used to establish a Redis or Sidekiq connection.

For example:

<CodeGroup>
  ```ruby Ruby theme={null}
  # config/initializers/appsignal.rb or a file that's loaded on boot

  # Ruby gem 2.11.0 and newer
  Appsignal::Minutely.probes.register(
    :sidekiq, # Use the same key as the default Sidekiq probe to override it
    Appsignal::Probes::SidekiqProbe.new(:hostname => "my_sidekiq_hostname")
  )

  # Ruby gem 2.10.x and older
  Appsignal::Minutely.probes.register(
    :sidekiq, # Use the same key as the default Sidekiq probe to override it
    Appsignal::Hooks::SidekiqProbe.new(:hostname => "my_sidekiq_hostname")
  )
  ```
</CodeGroup>

In version 2.11.0 of the Ruby gem, the `SidekiqProbe` constant was moved to its own module. Upon calling the constant, a warning will be printed and logged. Update to the new constant name `Appsignal::Probes::SidekiqProbe` to remove the warning.
