# Solid Queue Setup

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-thibautbaissac-rails-ai-agents-solid-queue-setup`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ThibautBaissac](https://agentstack.voostack.com/s/thibautbaissac)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ThibautBaissac](https://github.com/ThibautBaissac)
- **Source:** https://github.com/ThibautBaissac/rails_ai_agents/tree/main/.claude/skills/solid-queue-setup
- **Website:** https://thibautbaissac.github.io/

## Install

```sh
agentstack add skill-thibautbaissac-rails-ai-agents-solid-queue-setup
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Solid Queue Setup for Rails 8

## Overview

Solid Queue is Rails 8's default Active Job backend:
- Database-backed (no Redis required)
- Built-in concurrency controls
- Supports priorities and multiple queues
- Mission-critical job processing
- Web UI available via Mission Control

## Quick Start

### Installation

```bash
# Add to Gemfile (included in Rails 8 by default)
bundle add solid_queue

# Install Solid Queue
bin/rails solid_queue:install

# Run migrations
bin/rails db:migrate
```

### Configuration

```yaml
# config/solid_queue.yml
default: &default
  dispatchers:
    - polling_interval: 1
      batch_size: 500
  workers:
    - queues: "*"
      threads: 3
      processes: 1
      polling_interval: 0.1

development:
  <<: *default

production:
  <<: *default
  workers:
    - queues: [critical, default]
      threads: 5
      processes: 2
    - queues: [low]
      threads: 2
      processes: 1
```

### Set as Active Job Adapter

```ruby
# config/application.rb
config.active_job.queue_adapter = :solid_queue

# Or per environment
# config/environments/production.rb
config.active_job.queue_adapter = :solid_queue
```

## Workflow Checklist

```
Solid Queue Setup:
- [ ] Add solid_queue gem
- [ ] Run solid_queue:install
- [ ] Run migrations
- [ ] Configure queues in solid_queue.yml
- [ ] Set queue adapter in config
- [ ] Create first job with spec
- [ ] Test job execution
- [ ] Configure recurring jobs (if needed)
```

## Creating Jobs

### Basic Job

```ruby
# app/jobs/send_welcome_email_job.rb
class SendWelcomeEmailJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)
    UserMailer.welcome(user).deliver_now
  end
end
```

### Job with Retries

```ruby
# app/jobs/process_payment_job.rb
class ProcessPaymentJob < ApplicationJob
  queue_as :critical

  # Retry on specific errors
  retry_on PaymentGatewayError, wait: :polynomially_longer, attempts: 5

  # Don't retry on these
  discard_on ActiveRecord::RecordNotFound

  # Custom error handling
  rescue_from(StandardError) do |exception|
    ErrorNotifier.notify(exception)
    raise # Re-raise to trigger retry
  end

  def perform(order_id)
    order = Order.find(order_id)
    PaymentService.new.charge(order)
  end
end
```

### Job with Priority

```ruby
class UrgentNotificationJob < ApplicationJob
  queue_as :critical

  # Lower number = higher priority
  # Default is 0
  def priority
    -10
  end

  def perform(notification_id)
    # Process urgent notification
  end
end
```

## Enqueueing Jobs

```ruby
# Enqueue immediately
SendWelcomeEmailJob.perform_later(user.id)

# Enqueue with delay
SendReminderJob.set(wait: 1.hour).perform_later(user.id)

# Enqueue at specific time
SendReportJob.set(wait_until: Date.tomorrow.noon).perform_later

# Enqueue on specific queue
ProcessJob.set(queue: :low).perform_later(data)

# Perform immediately (skips queue - use sparingly)
SendWelcomeEmailJob.perform_now(user.id)
```

## Recurring Jobs

```yaml
# config/recurring.yml
production:
  daily_report:
    class: GenerateDailyReportJob
    schedule: every day at 6am
    queue: low

  cleanup:
    class: CleanupOldRecordsJob
    schedule: every sunday at 2am

  sync:
    class: SyncExternalDataJob
    schedule: every 15 minutes
```

## Testing Jobs

### Job Spec Template

```ruby
# spec/jobs/send_welcome_email_job_spec.rb
require 'rails_helper'

RSpec.describe SendWelcomeEmailJob, type: :job do
  let(:user) { create(:user) }

  describe '#perform' do
    it 'sends welcome email' do
      expect {
        described_class.perform_now(user.id)
      }.to have_enqueued_mail(UserMailer, :welcome)
    end
  end

  describe 'enqueueing' do
    it 'enqueues the job' do
      expect {
        described_class.perform_later(user.id)
      }.to have_enqueued_job(described_class)
        .with(user.id)
        .on_queue('default')
    end
  end

  describe 'retry behavior' do
    it 'retries on PaymentGatewayError' do
      expect(described_class).to have_retry_on(PaymentGatewayError)
    end
  end
end
```

### Test Helpers

```ruby
# spec/rails_helper.rb
RSpec.configure do |config|
  config.include ActiveJob::TestHelper
end

# In specs
it 'processes all jobs' do
  perform_enqueued_jobs do
    UserSignupService.call(user_params)
  end
  expect(user.reload.welcome_email_sent?).to be true
end

it 'enqueues multiple jobs' do
  expect {
    BatchProcessor.process(items)
  }.to have_enqueued_job(ProcessItemJob).exactly(items.count).times
end
```

## Running Solid Queue

```bash
# Development (runs in separate terminal)
bin/rails solid_queue:start

# Production (via Procfile)
# Procfile
web: bin/rails server
worker: bin/rails solid_queue:start
```

## Monitoring

### Mission Control (Web UI)

```ruby
# Gemfile
gem "mission_control-jobs"

# config/routes.rb
mount MissionControl::Jobs::Engine, at: "/jobs"
```

### Console Queries

```ruby
# Check pending jobs
SolidQueue::Job.where(finished_at: nil).count

# Check failed jobs
SolidQueue::FailedExecution.count

# Retry failed job
SolidQueue::FailedExecution.last.retry

# Clear old completed jobs
SolidQueue::Job.where('finished_at < ?', 1.week.ago).delete_all
```

## Migration from Sidekiq

| Sidekiq | Solid Queue |
|---------|-------------|
| `perform_async(args)` | `perform_later(args)` |
| `perform_in(5.minutes, args)` | `set(wait: 5.minutes).perform_later(args)` |
| `sidekiq_options queue: 'critical'` | `queue_as :critical` |
| `sidekiq_retry_in` | `retry_on` with `wait:` |

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ThibautBaissac](https://github.com/ThibautBaissac)
- **Source:** [ThibautBaissac/rails_ai_agents](https://github.com/ThibautBaissac/rails_ai_agents)
- **License:** MIT
- **Homepage:** https://thibautbaissac.github.io/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-thibautbaissac-rails-ai-agents-solid-queue-setup
- Seller: https://agentstack.voostack.com/s/thibautbaissac
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
