【完全版】Rails Solid Queue の使い方|セットアップから本番運用・Sidekiqからの移行まで徹底解説

【完全版】Rails Solid Queue の使い方|セットアップから本番運用・Sidekiqからの移行まで徹底解説

Rails 8 で デフォルトの Active Job バックエンド となった solid_queue は、データベース駆動のジョブシステムです。Sidekiq と違って Redis が不要で、インフラ構成がシンプルになります。

# Rails 8 では config/application.rb で既定
config.active_job.queue_adapter = :solid_queue

しかし、Sidekiq 時代の知識のままだと:

  • インストール後どう設定すれば?
  • ワーカーの起動はどうやる?
  • 並行性制御は?
  • スケジュールジョブ(cron的なもの)はどう書く?
  • 本番ではどうデプロイ?
  • 既存のSidekiqからの移行手順は?

など、戸惑うポイントが多くあります。

本記事では、Solid Queue のすべての使い方を、セットアップから本番運用、Sidekiqからの移行まで実用視点で網羅します。queue.yml設定、ジョブ作成・優先度・並行性制御、Mission Control UI、bin/jobs と Puma Plugin、recurring jobs、Kamalデプロイ、パフォーマンスチューニング、FAQまで完全網羅。この1本で Solid Queue を実戦投入できるようになります。


目次

結論:今すぐ使える3ステップ

時間がない方向けに、最短のセットアップ手順を示します。

ステップ1:インストール

# Rails 8 では既に含まれている。既存アプリへの追加なら:
bundle add solid_queue
bin/rails solid_queue:install
bin/rails db:migrate

ステップ2:設定

# config/environments/production.rb
config.active_job.queue_adapter = :solid_queue

ステップ3:起動

# 開発・本番でワーカー起動
bin/jobs

# またはPumaに統合(本番向け)
# SOLID_QUEUE_IN_PUMA=1 で puma が監視

これで Solid Queue でジョブが実行されます。詳細は以下で解説します。


まず押さえる:Solid Queue とは

概要

Solid Queue は Basecamp が開発し、Rails 8 から標準採用されたデータベース駆動のジョブキュー実装です。

特徴内容
バックエンドデータベース(PostgreSQL / MySQL / SQLite)
Redis依存なし
Active Job 統合ネイティブサポート
本番性能FOR UPDATE SKIP LOCKED で並行処理
管理UIMission Control jobs(別Gem)
対応Rails7.1以上で利用可、8.0以降は標準
対応Ruby3.2以上(Rails 8.1+ は3.3+)

仕組み

Solid Queue は 3つのコンポーネント から構成されます:

  1. Worker(ワーカー): ジョブを実行するプロセス
  2. Dispatcher(ディスパッチャー): ジョブをキューから取り出してワーカーに割り当て
  3. Scheduler(スケジューラ): 定期実行ジョブをエンキュー

これらが bin/jobs コマンドや Puma Plugin で起動され、データベースをポーリングして動作します。

Sidekiq との違い

観点SidekiqSolid Queue
ストレージRedisDB(PG/MySQL/SQLite)
必要な外部サービスRedisなし
永続性RDB(要設定)デフォルトで永続化
スループット高(数万/秒)中(千〜数千/秒)
管理UISidekiq Pro/Enterpriseに含むMission Control(無料)
並行性制御Pro/Enterprise標準搭載
コストPro/Enterpriseは有料完全無料
学習コスト
Active Job統合ありネイティブ

結論: 中小規模ならSolid Queue、大規模・高頻度ジョブならSidekiq継続が現実的。


インストールとセットアップ

Rails 8 新規プロジェクト

rails new myapp
# Solid Queue は既に設定済み
bin/rails db:prepare

開発環境では db/queue_schema.rb から自動でテーブルが生成されます。

Rails 7.1+ への追加

# Gemfile に追加
bundle add solid_queue

# セットアップコマンド実行
bin/rails solid_queue:install

# 生成されるもの:
# - db/migrate/xxx_create_solid_queue_tables.rb
# - config/queue.yml
# - config/recurring.yml(recurring jobs用)
# - bin/jobs

bin/rails db:migrate

既存Rails 8アプリでのSolid Queue 有効化

Rails 8 では config/application.rb で:

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

または環境別:

# config/environments/production.rb
config.active_job.queue_adapter = :solid_queue

データベース設計:単一DB vs マルチDB

Solid Queue は専用DB分離を推奨しています。ジョブ大量実行時にメインDBがロックの影響を受けないようにするためです。

パターン1:単一DB(簡易構成)

小規模アプリ向け。同じDB内にSolid Queueテーブルを作成:

# config/database.yml
production:
  <<: *default
  database: myapp_production
# config/environments/production.rb
config.active_job.queue_adapter = :solid_queue
# connects_to は指定しない

シンプルですが、ジョブが大量にあるとメインアプリケーションのクエリと競合します。

パターン2:マルチDB(推奨)

# config/database.yml
production:
  primary:
    <<: *default
    database: myapp_production
  queue:
    <<: *default
    database: myapp_production_queue
    migrations_paths: db/queue_migrate
# config/environments/production.rb
config.active_job.queue_adapter = :solid_queue
config.solid_queue.connects_to = { database: { writing: :queue } }

メインDBと分離されたDBでジョブが管理されます。マイグレーションも分離:

bin/rails db:migrate
# queue DB を含めて実行される

Solid Trifecta 完全分離

Solid Cache、Cable と合わせて4つのDBに分離する構成:

production:
  primary:
    <<: *default
    database: myapp_production
  cache:
    <<: *default
    database: myapp_production_cache
    migrations_paths: db/cache_migrate
  queue:
    <<: *default
    database: myapp_production_queue
    migrations_paths: db/queue_migrate
  cable:
    <<: *default
    database: myapp_production_cable
    migrations_paths: db/cable_migrate

Rails 8 の新規プロジェクトでは自動的にこの構成になります。


config/queue.yml の書き方

Solid Queue の挙動を制御する中心的なファイルです。

基本構造

# config/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
      polling_interval: 0.1
    - queues: [mailers, low]
      threads: 2
      processes: 1
      polling_interval: 1

dispatchers の設定

設定意味
polling_intervalDB をポーリングする間隔(秒)
batch_size1回のポーリングで処理するジョブ数
concurrency_maintenance_interval並行性制御の定期メンテ間隔
dispatchers:
  - polling_interval: 1
    batch_size: 500
    concurrency_maintenance_interval: 300

workers の設定

設定意味
queuesこのワーカーが処理するキュー名
threadsプロセス内のスレッド数
processesこのセットのプロセス数
polling_intervalDBポーリング間隔
workers:
  # 重要キュー専用ワーカー(高並行性)
  - queues: [critical]
    threads: 10
    processes: 2
    polling_interval: 0.1
  
  # 一般キュー
  - queues: [default, mailers]
    threads: 5
    processes: 2
    polling_interval: 0.5
  
  # 低優先度・重い処理
  - queues: [reports, batch]
    threads: 2
    processes: 1
    polling_interval: 5

キューの優先順位

queues 配列内の順序で優先度が決まります:

workers:
  - queues: [critical, default, low]
    # critical を先に処理し、なければ default、それも空なら low

または * で全キュー:

workers:
  - queues: "*"

ジョブの作成

Solid Queue は Active Job のバックエンドなので、ジョブの書き方は通常通り:

# app/jobs/welcome_email_job.rb
class WelcomeEmailJob < ApplicationJob
  queue_as :default
  
  def perform(user_id)
    user = User.find(user_id)
    UserMailer.welcome(user).deliver_now
  end
end

キュー名の指定

class CriticalJob < ApplicationJob
  queue_as :critical
  
  def perform(...)
    # ...
  end
end

config/queue.yml で定義したキュー名と一致させます。

ジョブの実行(エンキュー)

# 即時実行(非同期)
WelcomeEmailJob.perform_later(user.id)

# 5分後に実行
WelcomeEmailJob.set(wait: 5.minutes).perform_later(user.id)

# 特定時刻に実行
WelcomeEmailJob.set(wait_until: Date.tomorrow.beginning_of_day).perform_later(user.id)

# 優先度指定(後述)
WelcomeEmailJob.set(priority: 10).perform_later(user.id)

# 同期実行(テスト・デバッグ用)
WelcomeEmailJob.perform_now(user.id)

数値優先度(priority)の使い方

キューの順序とは別に、ジョブごとに数値優先度を指定できます。

優先度の仕組み

  • 小さい数字 = 高優先
  • 同じキュー内で優先度順に実行
  • デフォルトは 0

コード内での指定

class OrderConfirmationJob < ApplicationJob
  queue_as :default
  queue_with_priority 1   # 高優先
  
  def perform(order_id)
    # 緊急処理
  end
end

class WeeklyReportJob < ApplicationJob
  queue_as :default
  queue_with_priority 100  # 低優先
  
  def perform
    # 重い集計
  end
end

エンキュー時に優先度を上書き

SomeJob.set(priority: 5).perform_later(args)

キュー順序と優先度の組み合わせ

# queue.yml
workers:
  - queues: [critical, default]
class JobA < ApplicationJob
  queue_as :critical
  queue_with_priority 10
end

class JobB < ApplicationJob
  queue_as :default
  queue_with_priority 1   # 数値は小さいが、critical キューより後回し
end

JobA(critical)がJobB(default)より先に実行されます。


並行性制御(Concurrency Control)

Solid Queue の強みのひとつ。同時実行ジョブの数を制限できます。

基本:limits_concurrency

class UserSyncJob < ApplicationJob
  queue_as :default
  
  # ユーザーごとに同時1件のみ実行
  limits_concurrency to: 1, key: ->(user_id) { user_id }
  
  def perform(user_id)
    user = User.find(user_id)
    # 重い同期処理
  end
end

key で指定したキーごとに、to: で指定した数までしか並行実行されない。

用途例:データ更新の競合防止

class ProductPriceUpdateJob < ApplicationJob
  limits_concurrency to: 1, key: ->(product_id) { product_id }
  
  def perform(product_id, new_price)
    product = Product.find(product_id)
    product.update!(price: new_price)
  end
end

# 同じ product_id への並列更新は順序が保証される

待機時間の指定

class APIJob < ApplicationJob
  limits_concurrency to: 5, key: "api_calls", duration: 1.minute
  
  def perform(...)
    # APIレート制限考慮(1分間に5並列まで)
  end
end

duration: でロック期限を指定。デフォルトは 3.minutes

グループ単位の並行性

class HeavyComputeJob < ApplicationJob
  limits_concurrency to: 3, group: "heavy_computation"
  
  def perform(...)
    # 全ジョブ通して3並列まで
  end
end

group: を指定すると、複数の異なるジョブクラスで並行性を共有可能。


リトライとエラーハンドリング

Active Job 標準の機能がそのまま使えます。

retry_on:特定エラーで自動リトライ

class APICallJob < ApplicationJob
  retry_on Net::OpenTimeout, wait: 5.seconds, attempts: 5
  retry_on ApiClient::TemporaryError, wait: :polynomially_longer, attempts: 10
  
  def perform(...)
    # ...
  end
end
wait: の値意味
5.seconds固定5秒待機
:exponentially_longer指数バックオフ
:polynomially_longer多項式バックオフ(Rails 7.1+)
Procカスタム計算

discard_on:リトライせず破棄

class UserUpdateJob < ApplicationJob
  discard_on ActiveRecord::RecordNotFound
  
  def perform(user_id)
    user = User.find(user_id)   # 見つからなければ破棄
    # ...
  end
end

rescue_from でカスタムハンドリング

class MyJob < ApplicationJob
  rescue_from(StandardError) do |exception|
    Rails.logger.error("Job failed: #{exception.message}")
    Bugsnag.notify(exception)
  end
end

失敗ジョブの確認・再実行

Mission Control UI(後述)または直接DB:

# 失敗ジョブ一覧
SolidQueue::FailedExecution.all

# 再実行
SolidQueue::FailedExecution.find(id).retry

# 削除
SolidQueue::FailedExecution.find(id).discard

定期実行ジョブ(Recurring Jobs)

Sidekiq でいう sidekiq-cron 相当の機能が標準搭載されています。

config/recurring.yml で定義

# config/recurring.yml
production:
  daily_report:
    class: DailyReportJob
    queue: reports
    schedule: every day at 9am
    args: [ "production" ]
  
  cleanup_old_logs:
    class: LogCleanupJob
    queue: maintenance
    schedule: "0 3 * * *"  # cron syntax
    args: [{ older_than: "30.days" }]
  
  hourly_check:
    class: HealthCheckJob
    schedule: every hour

スケジュール構文

形式
fugit syntax(人間可読)every day at 9am, every 5 minutes, monday at noon
cron syntax0 9 * * *, */5 * * * *

Cron構文の詳細はcrontab 書き方 例の記事を参照してください。

起動

dispatcher が自動でスケジュールを管理します:

bin/jobs

スケジュール状態の確認:

SolidQueue::RecurringTask.all

ワーカーの起動方法

方法1:bin/jobs コマンド

# デフォルト config/queue.yml で起動
bin/jobs

# または明示的に
bin/jobs start

# 設定ファイル指定
bin/jobs --config config/custom_queue.yml

# ヘルプ
bin/jobs --help

開発環境ではこれが最もシンプルです。

方法2:Puma Plugin(小規模本番向け)

# config/puma.rb
plugin :solid_queue

これで bin/rails server 起動時に自動的にワーカーも立ち上がります。

または環境変数で制御:

SOLID_QUEUE_IN_PUMA=1 bundle exec puma -C config/puma.rb

⚠️ Web サーバーと同居するため、ジョブが Web リクエスト処理に影響する可能性。本番では別プロセス推奨。

方法3:systemd(本番推奨)

/etc/systemd/system/solid_queue.service:

[Unit]
Description=Solid Queue Worker
After=network.target

[Service]
Type=simple
User=deploy
WorkingDirectory=/path/to/app
Environment="RAILS_ENV=production"
EnvironmentFile=/path/to/app/.env
ExecStart=/path/to/app/bin/jobs
Restart=on-failure
RestartSec=5
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable solid_queue
sudo systemctl start solid_queue
sudo systemctl status solid_queue

ログ確認:

sudo journalctl -u solid_queue -f

方法4:Kamal でのデプロイ

config/deploy.yml:

service: myapp
image: yourname/myapp

servers:
  web:
    - 192.168.1.100
  job:
    hosts:
      - 192.168.1.101
    cmd: bin/jobs

env:
  clear:
    SOLID_QUEUE_IN_PUMA: "0"
  secret:
    - RAILS_MASTER_KEY
    - DATABASE_URL
kamal deploy

これでweb サーバーとは別のサーバーでジョブワーカーが動作します。

方法5:Docker Compose

services:
  web:
    build: .
    command: bundle exec puma -C config/puma.rb
    ports:
      - "3000:3000"
    depends_on:
      - db
  
  jobs:
    build: .
    command: bin/jobs
    depends_on:
      - db
    environment:
      RAILS_ENV: production

Web と Jobs を別コンテナで動かす構成。


Mission Control jobs(管理UI)

Solid Queue を Web UI で管理できるGemです。

インストール

# Gemfile
gem "mission_control-jobs"
bundle install

ルーティング

# config/routes.rb
Rails.application.routes.draw do
  # 開発・ステージング
  mount MissionControl::Jobs::Engine, at: "/jobs"
  
  # 本番では認証必須
  authenticate :user, ->(u) { u.admin? } do
    mount MissionControl::Jobs::Engine, at: "/jobs"
  end
end

Basic 認証(簡易方式)

# config/application.rb
config.mission_control.jobs.base_controller_class = "ApplicationController"
config.mission_control.jobs.http_basic_auth_user = "admin"
config.mission_control.jobs.http_basic_auth_password = ENV["JOBS_UI_PASSWORD"]

UI の機能

  • 実行中・キュー待ち・失敗ジョブの一覧
  • ジョブの詳細・引数確認
  • 再実行・破棄
  • キュー一時停止
  • ワーカー状態確認
  • recurring tasks の管理
  • リアルタイム統計

Sidekiq Pro 相当の機能が無料で使えます。


Sidekiq からの移行手順

既存のSidekiq運用からSolid Queueに移行する手順です。

ステップ1:並行運用準備

# Gemfile
gem "sidekiq"        # 残す
gem "solid_queue"    # 追加
gem "mission_control-jobs"
bundle install
bin/rails solid_queue:install
bin/rails db:migrate

ステップ2:個別ジョブから移行

すべてを一度に切り替えるとリスクが高いため、ジョブ単位で:

# 段階1:新しいジョブだけ solid_queue
class NewFeatureJob < ApplicationJob
  self.queue_adapter = :solid_queue
  
  def perform(...)
    # ...
  end
end

# 段階2:既存ジョブは sidekiq継続
class ExistingJob < ApplicationJob
  self.queue_adapter = :sidekiq
  
  def perform(...)
    # ...
  end
end

ステップ3:デフォルトを切り替え

# config/application.rb
config.active_job.queue_adapter = :solid_queue
# 残したいジョブだけ個別指定
class CriticalLegacyJob < ApplicationJob
  self.queue_adapter = :sidekiq
  # ...
end

ステップ4:Sidekiq のキューを空にする

Sidekiqに残っているジョブを処理し終わるまで待ちます:

# Sidekiq の状態確認
Sidekiq::Queue.all.each do |q|
  puts "#{q.name}: #{q.size}"
end

# 全キュー空になるまで待機

ステップ5:Sidekiq を削除

# Gemfile
# gem "sidekiq"   # 削除

# config/sidekiq.yml も削除
# config/initializers/sidekiq.rb も削除
bundle install

スケジュールジョブの移行

sidekiq-cron を使っていた場合:

# 旧 config/sidekiq.yml
:schedule:
  daily_report:
    cron: "0 9 * * *"
    class: "DailyReportWorker"

# 新 config/recurring.yml
production:
  daily_report:
    class: DailyReportJob
    schedule: "0 9 * * *"

Sidekiq 固有機能の代替

Sidekiq 機能Solid Queue 代替
perform_in(5.minutes, args)set(wait: 5.minutes).perform_later(args)
Sidekiq::WorkerApplicationJob
sidekiq-cronconfig/recurring.yml
sidekiq-unique-jobslimits_concurrency
sidekiq-statusSolidQueue::Job.find_by(...)
Sidekiq Pro batches標準にはなし(自前実装が必要)

移行できないケース

以下が必要な場合、Sidekiq の継続を検討:

  • 毎秒数千ジョブ以上の超高頻度処理
  • Sidekiq Pro/Enterprise の固有機能(Batches、Rate Limit等)に強く依存
  • すでにSidekiq + Redis 運用が完璧で、変える理由が薄い

パフォーマンスチューニング

スループット改善のポイント

1. ポーリング間隔の最適化

workers:
  - queues: [critical]
    polling_interval: 0.1   # 100msごと
    threads: 10
  - queues: [low]
    polling_interval: 5     # 5秒ごと(あまり急がない)
    threads: 2

頻繁なポーリングはレスポンス良くなるが、DB負荷が増えます。

2. スレッド数

workers:
  - queues: "*"
    threads: 5         # I/O中心なら多め(5〜10)
    threads: 3         # CPU中心なら少なめ(3〜5)

ジョブの性質に応じて調整。

3. プロセス数

workers:
  - queues: [critical]
    processes: 2      # CPUコア数を超えない範囲
    threads: 5

合計の並行ジョブ数 = threads × processes

4. データベース設定

PostgreSQL の接続プール:

# config/database.yml
production:
  primary:
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  queue:
    pool: <%= ENV.fetch("SOLID_QUEUE_POOL") { 20 } %>

ワーカーのスレッド数より多めに。

5. キューの分離

workers:
  # 速いジョブ専用
  - queues: [fast]
    threads: 10
    polling_interval: 0.1
  # 遅いジョブ専用
  - queues: [slow]
    threads: 2
    polling_interval: 1

「速いジョブが遅いジョブに詰まる」現象を防ぎます。

ベンチマーク:スループット目安

環境期待値
PostgreSQL + SSD、適切な設定数百〜数千ジョブ/秒
MySQL + SSD数百〜数千ジョブ/秒
SQLite(適度なサイズ)数十〜数百ジョブ/秒
同条件のSidekiq数万ジョブ/秒

Sidekiqより遅いですが、ほとんどのWebアプリでは十分。

監視

-- 待機中ジョブ数
SELECT queue_name, COUNT(*) 
FROM solid_queue_jobs 
WHERE finished_at IS NULL 
GROUP BY queue_name;

-- 失敗ジョブ数
SELECT COUNT(*) FROM solid_queue_failed_executions;

-- 平均実行時間(過去1時間)
SELECT 
    queue_name,
    AVG(EXTRACT(EPOCH FROM (finished_at - created_at))) AS avg_seconds
FROM solid_queue_jobs
WHERE finished_at > NOW() - INTERVAL '1 hour'
GROUP BY queue_name;

外部監視ツール(Datadog、New Relic、Sentry)との連携も推奨。


トラブルシューティング

ジョブが実行されない

確認順序:

  1. ワーカーが起動しているか
ps aux | grep -i jobs
# または
sudo systemctl status solid_queue
  1. 設定が反映されているか
Rails.application.config.active_job.queue_adapter
# => :solid_queue
  1. DBに ジョブが入っているか
SolidQueue::Job.count
SolidQueue::ReadyExecution.count
  1. 適切なキューを処理しているか

config/queue.ymlqueues 設定を再確認。

マイグレーション エラー

ActiveRecord::PendingMigrationError: Migrations are pending
# 全DB分のマイグレーション実行
bin/rails db:migrate
# または明示的に queue DB
bin/rails db:migrate:queue

Mac で起動時にセグフォルト

PostgreSQL のC拡張ライブラリとmacOSで稀に発生。pgライブラリを再ビルド:

gem uninstall pg
gem install pg
bundle install

ジョブが大量に失敗している

# 失敗ジョブ一覧
SolidQueue::FailedExecution.includes(:job).limit(20).each do |fe|
  puts "#{fe.job.class_name}: #{fe.error[:message]}"
end

エラーメッセージから根本原因を特定。

メモリリーク

長時間稼働するワーカーでメモリが増え続ける場合:

# config/queue.yml に追加
workers:
  - queues: "*"
    threads: 5
    # ワーカーを定期的に再起動
    max_executions_per_worker: 5000

または systemd 側で定期再起動設定。

Queue サーバーへの SSH 接続エラー

Kamal デプロイ時、ジョブサーバー側のSSH関連トラブルが起きた場合はSSH host key verification failed の記事を参照。

Docker環境での容量エラー

Solid Queueテーブルが大きくなりDockerボリュームを圧迫することがあります。Docker no space left on device の記事を参考に対処を。


よくある質問(FAQ)

Q1. Solid Queue は Rails 7 でも使えますか?

Rails 7.1 以上 で利用可能。Gemfile に gem "solid_queue" を追加してインストールすればOKです。Rails 8 ではデフォルトで使えます。

Q2. SQLite で本番運用できますか?

可能です。Rails 8 の SQLite は WAL モードや並行性改善で本番運用可能なレベルに進化。ただしジョブ数が多い場合は PostgreSQL/MySQL を推奨。

Q3. Solid Queue は Sidekiq より遅いですか?

スループットは Sidekiq より低い(Redis vs DB の根本的な差)が、多くのアプリでは十分。毎秒数千ジョブの超高頻度処理が必要な場合のみ Sidekiq 継続を検討してください。

Q4. キューの一時停止はできますか?

可能です。Mission Control UI から、または:

SolidQueue::Pause.create!(queue_name: "default")
# 解除
SolidQueue::Pause.find_by(queue_name: "default").destroy

Q5. ワーカーがクラッシュしたジョブはどうなりますか?

SolidQueue::ClaimedExecution テーブルにロックされたまま残ります。Dispatcher が定期的に「孤児ジョブ」を検出して再投入します(concurrency_maintenance_interval 設定)。

Q6. ジョブの実行履歴を保持できますか?

デフォルトでは完了ジョブは削除されます。履歴を残したい場合:

# config/initializers/solid_queue.rb
SolidQueue.preserve_finished_jobs = true
SolidQueue.clear_finished_jobs_after = 7.days  # 7日後に削除

または自前で before_destroy フックで履歴テーブルに保存。

Q7. perform_later が同期実行されてしまいます

考えられる原因:

  • config.active_job.queue_adapter:async または :inline のまま
  • config.active_job.queue_adapter = :solid_queue の設定漏れ
  • ワーカーが起動していない
Rails.application.config.active_job.queue_adapter
# => :solid_queue  ← なっているか確認

Q8. 開発環境でもワーカーを動かすべきですか?

ローカルで非同期処理を確認したいなら起動推奨:

# 開発時に bin/dev でPuma + Tailwind + Jobs 同時起動
# Procfile.dev に追加
web: bin/rails server
jobs: bin/jobs

bin/dev で全部動きます。

Q9. Redis を使い続ける場合との比較

ケース推奨
Solid Cache/Cable も使うSolid Queue 推奨(Redis脱却)
Redis を Cache/Cable で使い続けるどちらでもOK
既存 Sidekiq + Redis が安定Sidekiq 継続でOK
新規プロジェクト・小〜中規模Solid Queue 推奨
大規模・超高頻度Sidekiq 継続

Q10. Active Job の他のバックエンドとの併用

可能です。ジョブクラス単位で self.queue_adapter を指定すれば異なるバックエンドを混在させられます:

class HighThroughputJob < ApplicationJob
  self.queue_adapter = :sidekiq
end

class NormalJob < ApplicationJob
  # デフォルトの solid_queue
end

ただし運用が複雑になるので、移行期以外では推奨しません。

Q11. Rails 8.1 で何が変わりましたか?

主な変更:

  • Job Continuations: 長時間ジョブを中断・再開できる新機能
  • 構造化ログ統合: Rails.event との連携改善
  • 細かいパフォーマンスチューニング

詳しくはRails 8 アップグレードガイドを参照。

Q12. Sidekiq Pro / Enterprise の代替機能はありますか?

Sidekiq Pro/Enterprise 機能Solid Queue
Batches❌ なし(自前実装)
Rate Limitinglimits_concurrency で代替可能
Unique Jobslimits_concurrency
Encryption❌ なし
Strict Priority✅ 標準対応
Web UI(高度版)✅ Mission Control(無料)

Batches など独自機能に依存している場合、Sidekiq 継続が現実的です。


参考リンク・関連資料

公式ドキュメント

関連プロジェクト

移行ガイド

関連記事(本サイト)


まとめ

Solid Queue はRails 8 の重要な新機能で、Redis 不要のジョブシステムを実現します。要点を再整理します。

  • シンプルなセットアップ: bin/rails solid_queue:install + db:migrate
  • マルチDB推奨: メインDB と queue DB を分離してパフォーマンス確保
  • 設定の中心: config/queue.yml で workers/dispatchers/queues を制御
  • 並行性制御: limits_concurrency で同時実行数を細かく管理
  • 優先度: キュー順序+数値優先度の二段構え
  • 定期実行: config/recurring.yml で cron 的なスケジュール
  • 起動方法: bin/jobs / Puma Plugin / systemd / Kamal
  • 管理UI: Mission Control jobs(無料・高機能)
  • Sidekiq 移行: 段階的にジョブ単位で切り替えるのが安全
  • 適性: 中小規模なら Solid Queue、超高頻度なら Sidekiq 継続

これらの知識は、Rails 8 アプリの設計・本番運用・Sidekiq からの移行などあらゆる場面で必須です。本記事をブックマークしておけば、Solid Queue を実戦投入できるようになります。


本記事は2026年6月時点の情報をもとに、Ruby on Rails 8.0.5 / 8.1.3 / 8.2.x、Solid Queue 最新版での動作確認・公式ドキュメントに基づき作成しています。Solid Queue は活発に開発されており、設定方法が更新される可能性があるため、最新の情報は公式リポジトリもあわせてご確認ください。