Background Jobs Rails di 2026: Sidekiq vs Good Job dan Pertanyaan Interview
Panduan lengkap memilih queue backend untuk Rails: perbandingan Sidekiq 8.x, Good Job 4.x, dan Solid Queue dengan fokus pada throughput, fitur, dan pertanyaan interview teknis.

Background jobs di Rails telah berkembang signifikan dengan hadirnya Rails 8.x dan diperkenalkannya Solid Queue sebagai backend Active Job default. Pemilihan antara Sidekiq, Good Job, dan Solid Queue bergantung pada kebutuhan throughput, batasan infrastruktur, dan fitur yang diperlukan oleh setiap proyek.
Untuk proyek Rails 8 baru, mulailah dengan Solid Queue. Beralih ke Sidekiq untuk workload tinggi yang melebihi 100.000 jobs/hari atau ketika latensi tingkat Redis diperlukan. Pilih Good Job untuk jobs berbasis PostgreSQL dengan fitur batch dan unique job constraints tanpa biaya lisensi.
Bagaimana Active Job Menyatukan Background Processing
Active Job menyediakan interface standar untuk mendeklarasikan, mengantrekan, dan mengeksekusi pekerjaan background di Rails. Framework ini mengabstraksi perbedaan antar queue backend, memungkinkan kode tetap portabel di Sidekiq, Good Job, Solid Queue, atau adapter lainnya.
# app/jobs/payment_processor_job.rb
class PaymentProcessorJob < ApplicationJob
queue_as :critical
retry_on Stripe::RateLimitError, wait: :polynomially_longer, attempts: 5
discard_on Stripe::InvalidRequestError
def perform(order_id)
order = Order.find(order_id)
PaymentService.process(order)
OrderMailer.confirmation(order).deliver_later
end
endCallback retry_on dan discard_on menangani kegagalan sementara dan error permanen tanpa kode spesifik backend. Direktif queue_as menetapkan prioritas, yang diinterpretasikan oleh setiap backend sesuai strategi pemrosesan queue masing-masing.
Sidekiq 8.x: Throughput Berbasis Redis
Sidekiq tetap menjadi baseline performa untuk background jobs Rails. Seri rilis 8.x memerlukan Ruby 3.2+, Rails 7.0+, dan Redis 7.2+ (Valkey dan Dragonfly dapat digunakan sebagai pengganti langsung sejak Redis mengubah lisensinya).
# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
config.redis = { url: ENV.fetch('REDIS_URL') }
config.concurrency = 10
end
Sidekiq.configure_client do |config|
config.redis = { url: ENV.fetch('REDIS_URL') }
endSidekiq 8 membawa tiga perubahan utama: Web UI yang ditulis ulang dari awal mengurangi CSS dari 160KB menjadi 16KB dan waktu render halaman rata-rata dari 55ms menjadi 3ms, job profiling dengan Vernier di tab Profiles baru, dan job metrics yang disimpan hingga 72 jam.
Kapan Sidekiq Tepat Digunakan
Sidekiq cocok untuk workload yang membutuhkan throughput berkelanjutan, latensi pickup job sub-milidetik, atau fitur enterprise seperti rate limiting dan unique jobs yang membenarkan penggunaan Redis. Capsules, yang diperkenalkan di 7.0 dan sekarang menjadi standar, memungkinkan satu proses Sidekiq menjalankan beberapa thread pool terisolasi dengan concurrency dan queue masing-masing.
# config/sidekiq.yml
:concurrency: 10
:queues:
- [critical, 3]
- [default, 2]
- [low, 1]
# Capsules untuk pemrosesan terisolasi
:capsules:
imports:
:concurrency: 2
:queues:
- importsAPI embedding juga memungkinkan Sidekiq berjalan di dalam proses Puma untuk aplikasi kecil, mirip dengan cara plugin Puma Solid Queue bekerja.
Siap menguasai wawancara Ruby on Rails Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Good Job 4.x: Batch dan Uniqueness Native PostgreSQL
Good Job menggunakan LISTEN/NOTIFY PostgreSQL untuk pickup job dan advisory locks untuk keamanan run-once. Versi 4.19.x (terkini per September 2026) mendukung Rails 6.1+ dan Ruby 3.0+.
# config/application.rb
config.active_job.queue_adapter = :good_job
# config/initializers/good_job.rb
Rails.application.configure do
config.good_job.execution_mode = :async
config.good_job.max_threads = 5
config.good_job.poll_interval = 5
config.good_job.shutdown_timeout = 25
endGood Job menyediakan batches dan unique jobs di tier open-source, fitur yang Sidekiq cadangkan untuk lisensi berbayar. Panggilan perform_later menyisipkan baris ke tabel good_jobs dalam transaksi database yang sama dengan kode pemanggil, sehingga jika transaksi rollback, job tidak pernah dibuat.
Batches Tanpa Lisensi
# app/jobs/batch_import_job.rb
class BatchImportJob < ApplicationJob
def perform(batch, params)
batch.on(:finish, ImportCompletionJob, params)
params[:file_ids].each do |file_id|
batch.add do
ProcessFileJob.perform_later(file_id)
end
end
end
end
# Enqueue batch
GoodJob::Batch.enqueue do |batch|
BatchImportJob.perform_later(batch, file_ids: [1, 2, 3])
endUnique Jobs untuk Idempotency
# app/jobs/sync_inventory_job.rb
class SyncInventoryJob < ApplicationJob
include GoodJob::ActiveJobExtensions::UniqueJob
good_job_control_concurrency_with(
perform_limit: 1,
key: -> { "sync_inventory_#{arguments.first}" },
duration: 1.hour
)
def perform(warehouse_id)
InventorySync.run(warehouse_id)
end
endKendala perform_limit: 1 memastikan hanya satu sync berjalan per warehouse pada satu waktu, mencegah pekerjaan duplikat ketika job yang sama di-enqueue beberapa kali.
Solid Queue: Default Rails 8
Solid Queue menyimpan jobs di database aplikasi menggunakan FOR UPDATE SKIP LOCKED, fitur PostgreSQL dan MySQL yang mengubah tabel biasa menjadi job queue. Aplikasi Rails 8 baru sudah dikonfigurasi dengan Solid Queue secara default.
# config/solid_queue.yml
production:
dispatchers:
- polling_interval: 1
batch_size: 500
workers:
- queues: "*"
threads: 5
polling_interval: 0.1Solid Queue dapat berjalan di dalam proses web server Puma dengan SOLID_QUEUE_IN_PUMA=true, yang menyederhanakan deployment untuk aplikasi yang tidak memerlukan proses worker terpisah. Jobs bertahan di tabel database, bertahan dari restart proses dan deployment tanpa dependensi eksternal.
Tabel Perbandingan Fitur
| Fitur | Sidekiq 8.x | Good Job 4.x | Solid Queue 1.x |
|---|---|---|---|
| Backend | Redis 7.2+ | PostgreSQL | PostgreSQL/MySQL/SQLite |
| Batches | Pro/Enterprise | Termasuk | Direncanakan |
| Unique jobs | Enterprise | Termasuk | Manual via locks |
| Cron scheduling | Enterprise | Termasuk | Via solid_queue_cron |
| Web UI | Termasuk | Termasuk | Minimal (Mission Control) |
| Batas throughput | 100k+ jobs/min | 10k jobs/min | 10k jobs/min |
| Embed di Puma | Ya (8.x) | Tidak | Ya |
| Lisensi | LGPL + Commercial | MIT | MIT |
Pertanyaan Interview tentang Rails Background Jobs
Interview teknis sering menguji pemahaman tentang reliabilitas job, strategi retry, dan keputusan arsitektur. Berikut pertanyaan yang membedakan kandidat berpengalaman.
Q1: Apa perbedaan retry_on dengan logika retry spesifik backend?
retry_on adalah callback Active Job yang bekerja di semua backend. Callback ini menangkap exception spesifik, menerapkan strategi wait (:polynomially_longer mundur secara eksponensial), dan meng-enqueue ulang job. Logika retry spesifik backend, seperti sidekiq_retry_in Sidekiq, hanya bekerja dengan backend tersebut dan dapat meng-override perilaku Active Job.
# Active Job retry (portabel)
class ApiSyncJob < ApplicationJob
retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 8
def perform(record_id)
ExternalApi.sync(record_id)
end
endQ2: Apa yang terjadi pada job jika transaksi database yang meng-enqueue-nya rollback?
Dengan queue berbasis database (Good Job, Solid Queue), baris job adalah bagian dari transaksi, sehingga rollback bersama yang lainnya. Dengan queue berbasis Redis (Sidekiq), job sudah ada di Redis sebelum transaksi selesai, menciptakan orphaned jobs. Solusinya adalah callback after_commit:
# Pola benar untuk Sidekiq
class Order < ApplicationRecord
after_commit :enqueue_confirmation, on: :create
private
def enqueue_confirmation
OrderConfirmationJob.perform_later(id)
end
endQ3: Kapan Good Job lebih unggul dari Sidekiq?
Good Job lebih unggul dari Sidekiq ketika biaya operasional Redis melebihi manfaat throughput-nya. Untuk aplikasi yang memproses kurang dari 50.000 jobs/hari, queue berbasis PostgreSQL menghindari kompleksitas infrastruktur, monitoring, dan failover dari cluster Redis terpisah. Good Job juga menyediakan batches dan unique jobs tanpa biaya lisensi, yang penting untuk tim yang membutuhkan fitur tersebut dengan anggaran terbatas.
Q4: Jelaskan idempotency job dan mengapa penting untuk retry
Idempotency berarti menjalankan job yang sama beberapa kali menghasilkan hasil yang sama seperti menjalankannya sekali. Jobs harus idempotent karena kegagalan jaringan, crash proses, atau penanganan timeout dapat menyebabkan eksekusi duplikat. Tekniknya termasuk unique constraints di database, memeriksa hasil yang sudah ada sebelum memproses, dan menggunakan idempotency keys eksternal untuk API pembayaran.
# Pemrosesan pembayaran idempotent
def perform(order_id, idempotency_key)
return if Payment.exists?(idempotency_key: idempotency_key)
Payment.create!(
order_id: order_id,
idempotency_key: idempotency_key,
amount: Order.find(order_id).total
)
endQ5: Bagaimana menangani jobs yang harus berjalan tepat sekali di seluruh distributed workers?
Distributed locks mencegah eksekusi bersamaan. Good Job menggunakan advisory locks PostgreSQL. Sidekiq Enterprise menawarkan unique jobs. Untuk implementasi manual, gunakan Redis SETNX atau PostgreSQL pg_try_advisory_lock:
class ExclusiveJob < ApplicationJob
def perform(resource_id)
lock_key = "exclusive_job:#{resource_id}"
ActiveRecord::Base.connection.execute(
"SELECT pg_try_advisory_lock(hashtext('#{lock_key}'))"
).first['pg_try_advisory_lock'] or return
begin
process_resource(resource_id)
ensure
ActiveRecord::Base.connection.execute(
"SELECT pg_advisory_unlock(hashtext('#{lock_key}'))"
)
end
end
endMulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Memilih Backend yang Tepat untuk Rails Background Jobs
- Mulai dengan Solid Queue untuk proyek Rails 8 baru yang belum memiliki Redis di stack
- Beralih ke Sidekiq ketika volume job melebihi 50.000/hari atau latensi pickup di bawah 100ms diperlukan
- Pilih Good Job untuk deployment PostgreSQL-only yang membutuhkan batches, unique jobs, atau cron scheduling tanpa biaya lisensi
- Gunakan callback
after_commitketika meng-enqueue jobs dengan Sidekiq untuk menghindari orphaned jobs pada rollback transaksi - Buat setiap job idempotent karena retry dan distributed processing dapat menyebabkan eksekusi duplikat
- Untuk interview, tunjukkan pemahaman tentang transactional job enqueuing, strategi retry, dan pola distributed locking
Bisakah kamu menemukan bug di Ruby on Rails?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 12 September 2026
Bagikan
Artikel terkait

Rails GraphQL API di 2026: graphql-ruby, Subscriptions, dan Pertanyaan Interview
Bangun GraphQL API siap produksi dengan Rails 8 dan graphql-ruby. Desain schema, mutations, subscriptions dengan ActionCable, dan persiapan interview.

Rails Active Storage 2026: Upload File, Integrasi S3, dan Pertanyaan Interview
Panduan lengkap Rails Active Storage untuk upload file, integrasi Amazon S3, dan persiapan pertanyaan interview Ruby on Rails.

Rails Stimulus dan Importmaps 2026: JavaScript Modern Tanpa Build Tools
Stimulus dan Importmaps di Rails 8.1 memungkinkan penulisan JavaScript modern tanpa bundler. Tutorial ini membahas controller, action, target, dan package npm.