Solid Queue dan Solid Cache di Rails 8: Panduan Lengkap untuk Persiapan Interview Teknis 2026

Pembahasan mendalam tentang Solid Queue dan Solid Cache sebagai komponen default berbasis database di Rails 8. Meliputi arsitektur, konfigurasi, kontrol concurrency, mekanisme caching, serta pertanyaan interview teknis yang sering diajukan di tahun 2026.

Arsitektur Solid Queue dan Solid Cache pada Rails 8 dengan pemrosesan job dan caching berbasis database

Kehadiran Solid Queue dan Solid Cache di Rails 8 menandai pergeseran infrastruktur paling besar dalam sejarah framework Ruby on Rails. Kedua komponen ini disertakan sebagai default, menggantikan peran Redis untuk pengelolaan background jobs dan caching dengan pendekatan berbasis database yang menghilangkan satu lapisan kompleksitas operasional secara menyeluruh. Bagi pengembang yang selama ini bergantung pada Redis sebagai komponen wajib dalam stack Rails, perubahan ini menghadirkan paradigma baru yang perlu dipahami secara mendalam.

Dalam konteks persiapan interview teknis, penguasaan terhadap arsitektur Solid Stack menjadi semakin krusial. Pertanyaan seputar cara kerja database-backed queue, perbandingan dengan Sidekiq, serta strategi deployment untuk production semakin sering diajukan dalam sesi interview Rails sepanjang tahun 2026. Artikel ini membahas secara menyeluruh implementasi teknis, konfigurasi production-ready, dan pertanyaan interview yang paling relevan untuk kedua komponen tersebut.

Trifecta Solid pada Rails 8

Rails 8 mengadopsi tiga komponen berbasis database sebagai default: Solid Queue untuk background jobs, Solid Cache untuk cache store, dan Solid Cable untuk WebSockets. Ketiga komponen ini secara kolektif menghapus kebutuhan akan Redis pada sebagian besar aplikasi Rails. Topik ini termasuk salah satu yang paling sering diujikan dalam interview teknis Rails 8 saat ini.

Cara Kerja Solid Queue Menggantikan Backend Job Berbasis Redis

Solid Queue merupakan backend Active Job berbasis database yang menyimpan job secara langsung di PostgreSQL, MySQL, atau SQLite. Mekanisme utama yang mendasari kinerjanya adalah FOR UPDATE SKIP LOCKED -- sebuah fitur SQL yang tersedia di PostgreSQL 9.5+ dan MySQL 8+ yang memungkinkan tabel database biasa berfungsi sebagai antrian job konkuren tanpa terjadi blocking antar proses.

Arsitektur Solid Queue dibangun dari tiga komponen utama:

  • Workers melakukan polling pada tabel solid_queue_ready_executions dan mengklaim job menggunakan mekanisme SKIP LOCKED
  • Dispatchers bertugas memindahkan scheduled jobs dari tabel solid_queue_scheduled_executions ke tabel ready begitu waktu eksekusi tiba
  • Schedulers menangani recurring tasks yang didefinisikan dalam file konfigurasi
ruby
# config/solid_queue.yml
production:
  dispatchers:
    - polling_interval: 1
      batch_size: 500
  workers:
    - queues: "*"
      threads: 5
      polling_interval: 0.1
      processes: 2

Konfigurasi di atas menjalankan dua proses worker dengan masing-masing 5 thread, yang melakukan polling setiap 100 milidetik. Dispatcher memeriksa ketersediaan scheduled jobs setiap satu detik dengan ukuran batch sebanyak 500 entri. Parameter polling_interval dan batch_size perlu disesuaikan berdasarkan karakteristik beban kerja masing-masing aplikasi -- nilai yang terlalu rendah pada polling interval dapat menimbulkan overhead pada database, sementara nilai yang terlalu tinggi menyebabkan latensi eksekusi job meningkat.

Transactional Job Enqueuing pada Rails 8

Salah satu keunggulan paling signifikan Solid Queue dibandingkan backend berbasis Redis terletak pada fitur transactional enqueuing. Ketika sebuah job di-enqueue di dalam transaksi database, job tersebut baru menjadi visible setelah transaksi berhasil di-commit. Backend berbasis Redis tidak mampu memberikan jaminan serupa -- sebuah job berpotensi tereksekusi sebelum transaksi yang memicunya selesai, sehingga mereferensikan record yang belum tersimpan di database.

ruby
# app/jobs/send_welcome_email_job.rb
class SendWelcomeEmailJob < ApplicationJob
  self.enqueue_after_transaction_commit = true

  queue_as :default

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

# app/models/user.rb
class User < ApplicationRecord
  after_create do
    SendWelcomeEmailJob.perform_later(id)
    # Job only enqueued after the CREATE transaction commits
    # No risk of the job running before the user record exists
  end
end

Dengan mengaktifkan enqueue_after_transaction_commit, eksekusi job ditunda hingga transaksi pembungkus berhasil. Apabila transaksi mengalami rollback, job tidak akan pernah di-enqueue. Mekanisme ini mengeliminasi seluruh kelas race condition yang kerap mengganggu sistem berbasis Redis, di mana job bisa tereksekusi lebih cepat dibandingkan proses commit transaksi yang memicunya.

Dalam konteks interview teknis, kemampuan menjelaskan transactional enqueuing secara detail menunjukkan pemahaman mendalam tentang konsistensi data. Kandidat yang mampu mendeskripsikan skenario kegagalan konkret -- seperti error ActiveRecord::RecordNotFound pada job yang berjalan sebelum record tersimpan -- memberikan kesan penguasaan yang matang terhadap tantangan production-grade.

Kontrol Concurrency dan Priority Queue

Solid Queue menyediakan mekanisme kontrol concurrency bawaan yang pada Sidekiq hanya tersedia melalui tier berbayar Enterprise. Opsi limits_concurrency membatasi jumlah job dari tipe tertentu yang boleh berjalan secara simultan, mencegah overload terhadap resource eksternal.

ruby
# app/jobs/api_sync_job.rb
class ApiSyncJob < ApplicationJob
  limits_concurrency to: 3, key: ->(account_id) { "api_sync_#{account_id}" }

  def perform(account_id)
    account = Account.find(account_id)
    ExternalApi.sync(account)
  end
end

Konfigurasi tersebut memastikan bahwa maksimal 3 job API sync berjalan secara bersamaan untuk setiap akun, sehingga mencegah pelanggaran rate limit dari external API tanpa memerlukan koordinasi tambahan. Job yang tertunda disimpan dalam tabel solid_queue_blocked_executions dan secara otomatis dirilis begitu slot tersedia kembali.

Sistem prioritas pada Solid Queue beroperasi pada dua tingkatan: prioritas numerik per job (angka lebih rendah berarti prioritas lebih tinggi) dan urutan queue dalam konfigurasi worker. Kedua mekanisme ini dapat dikombinasikan untuk memperoleh kontrol granular terhadap urutan eksekusi job. Sebagai contoh, queue payments dapat diprioritaskan di atas queue notifications untuk memastikan transaksi keuangan selalu diproses terlebih dahulu.

Wawasan untuk Interview

Pertanyaan interview Rails 8 yang sangat umum membahas perbandingan antara Solid Queue dan Sidekiq. Perbedaan kuncinya: Solid Queue menawarkan jaminan transaksional dan kontrol concurrency bawaan tanpa biaya tambahan. Sidekiq unggul pada raw throughput untuk beban kerja bervolume tinggi (10.000+ jobs per menit) karena Redis beroperasi secara in-memory. Untuk 95% aplikasi Rails, performa Solid Queue sudah lebih dari memadai.

Recurring Jobs Tanpa Cron

Solid Queue menggantikan kebutuhan penjadwalan berbasis cron dengan scheduler bawaan yang terintegrasi penuh. Tugas-tugas berulang didefinisikan dalam file konfigurasi YAML dan dikelola oleh proses scheduler secara terpusat.

ruby
# config/recurring.yml
production:
  cleanup_expired_sessions:
    class: CleanupExpiredSessionsJob
    schedule: every 6 hours
  daily_report:
    class: DailyReportJob
    schedule: every day at 6am
    queue: reports
  weekly_digest:
    class: WeeklyDigestJob
    schedule: every Monday at 9am

Proses scheduler membaca file konfigurasi ini dan meng-enqueue job yang sesuai pada interval yang telah ditentukan. Berbeda dengan cron yang memerlukan konfigurasi terpisah di level sistem operasi, scheduler Solid Queue berjalan dalam process supervisor yang sama dan berbagi koneksi database yang identik. Pendekatan ini menyederhanakan proses deployment secara signifikan karena tidak perlu mengelola crontab terpisah di server.

Keuntungan tambahan dari pendekatan berbasis YAML adalah portabilitas konfigurasi antar environment. Tim pengembang dapat mendefinisikan jadwal yang berbeda untuk development, staging, dan production hanya dengan menyesuaikan file konfigurasi, tanpa mengubah satu baris pun kode aplikasi.

Deployment dengan Integrasi Puma

Rails 8 yang dikombinasikan dengan Kamal menyediakan deployment tanpa konfigurasi tambahan untuk Solid Queue. Pengaturan variabel environment SOLID_QUEUE_IN_PUMA=1 menginstruksikan Puma untuk melakukan fork dan mengawasi proses Solid Queue secara bersamaan dengan web server.

ruby
# config/puma.rb (Rails 8 default)
plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"]

Model deployment single-process ini menyederhanakan orkestrasi container secara substansial. Satu Docker image dapat menjalankan web server dan job processor sekaligus, mengurangi overhead operasional untuk aplikasi berskala kecil hingga menengah. Bagi aplikasi yang lebih besar dengan kebutuhan scaling independen, proses Solid Queue tetap dapat dijalankan sebagai service terpisah dengan konfigurasi resource tersendiri.

Siap menguasai wawancara Ruby on Rails Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Solid Cache: Arsitektur Caching Berbasis Database yang Skalabel

Solid Cache adalah implementasi ActiveSupport::Cache::Store berbasis database yang memanfaatkan performa SSD modern untuk menggantikan Redis dan Memcached sebagai cache store default di Rails 8. Premis dasar di balik desainnya cukup sederhana: SSD hanya sedikit lebih lambat dibandingkan RAM untuk operasi baca, namun menawarkan kapasitas penyimpanan yang jauh lebih besar dengan biaya yang secara signifikan lebih rendah.

Solid Cache menggunakan strategi expiry FIFO (First In, First Out) alih-alih LRU (Least Recently Used) yang umum digunakan oleh Redis. Meskipun FIFO secara teoretis kurang efisien dalam menentukan entri mana yang harus dihapus, kapasitas penyimpanan SSD yang jauh lebih besar memberikan kompensasi yang lebih dari cukup -- entri cache bertahan jauh lebih lama, sehingga menurunkan tingkat cache miss secara keseluruhan.

ruby
# config/environments/production.rb
config.cache_store = :solid_cache_store

# config/solid_cache.yml
production:
  databases:
    - cache
  store_options:
    max_age: 604800        # 1 week in seconds
    max_size: 256           # Max entry size in KB
    namespace: "app_v1"
    expiry_batch_size: 100  # Entries cleaned per expiry cycle

Parameter max_age menentukan durasi maksimal entri cache bertahan sebelum dianggap expired, dinyatakan dalam satuan detik. max_size membatasi ukuran maksimal setiap entri dalam kilobyte. Penggunaan namespace sangat bermanfaat untuk invalidasi cache saat deployment versi baru -- cukup mengubah nilai namespace dan seluruh entri cache lama secara efektif ter-invalidasi tanpa perlu proses penghapusan manual.

Mekanisme Expiry Cache: FIFO versus LRU

Solid Cache melacak operasi write menggunakan counter internal. Ketika counter mencapai 50% dari nilai expiry_batch_size yang dikonfigurasi, sebuah tugas background secara otomatis terpicu untuk membersihkan entri yang telah expired. Pendekatan amortized ini menghindari jeda stop-the-world yang sering terjadi pada eviction LRU di Redis instance dengan kapasitas memori terbatas.

Tabel solid_cache_entries menyimpan seluruh data cache dalam format berikut:

ruby
# db/cache_schema.rb (generated by installer)
create_table :solid_cache_entries do |t|
  t.binary :key, null: false, limit: 1024
  t.binary :value, null: false, limit: 262144  # 256 KB default
  t.datetime :created_at, null: false
  t.index :key, unique: true
  t.index :created_at  # For FIFO expiry
end

Index unik pada kolom key menjamin efisiensi operasi lookup, sementara index pada created_at mendukung strategi expiry FIFO dengan memungkinkan penghapusan entri terlama secara terurut. Operasi baca dan tulis pada tabel ini secara default menggunakan connection pool yang sama dengan aplikasi utama. Untuk aplikasi dengan traffic tinggi, konfigurasi database terpisah untuk data cache menjadi langkah penting guna mencegah operasi cache mempengaruhi performa database utama.

Konfigurasi Database Terpisah untuk Cache

Memisahkan Solid Cache ke database yang dedicated merupakan langkah yang relatif mudah dilakukan dan sangat direkomendasikan untuk beban kerja production yang menghasilkan traffic cache dalam volume besar.

yaml
# config/database.yml
production:
  primary:
    <<: *default
    database: myapp_production
  cache:
    <<: *default
    database: myapp_cache_production
    migrations_paths: db/cache_migrate

Pemisahan ini menjamin bahwa jutaan operasi write cache tidak membengkakkan WAL (Write-Ahead Log) database utama atau bersaing memperebutkan slot connection pool dengan query aplikasi. Konfigurasi migrations_paths yang terpisah juga memberikan kemudahan dalam mengelola skema database cache secara independen dari skema aplikasi utama, memungkinkan tim database melakukan optimasi yang spesifik untuk pola akses cache.

Pertimbangan Penting untuk Production

Tanpa database terpisah, operasi baca dan tulis Solid Cache akan turut berpartisipasi dalam setiap transaksi ActiveRecord yang sedang berjalan. Implikasinya, transaksi yang berjalan lama akan menahan entri cache dalam status uncommitted, berpotensi menyebabkan inkonsistensi data cache. Selalu konfigurasi database dedicated untuk cache pada lingkungan production.

Sharding dan Enkripsi Data Cache

Solid Cache mendukung distribusi data cache ke beberapa database melalui mekanisme sharding untuk menyebarkan beban secara merata. Selain itu, Solid Cache juga mendukung encrypted attributes -- data cache tetap terenkripsi saat disimpan (at rest), memenuhi persyaratan kepatuhan untuk aplikasi yang menangani informasi sensitif.

ruby
# config/solid_cache.yml
production:
  databases:
    - cache_shard_1
    - cache_shard_2
    - cache_shard_3
  store_options:
    max_age: 1209600  # 2 weeks

Entri didistribusikan ke shard menggunakan consistent hashing berdasarkan cache key. Penambahan atau penghapusan shard akan menyebabkan peningkatan sementara pada cache miss selama proses redistribusi berlangsung, namun tidak terjadi kehilangan data. Strategi sharding ini memungkinkan horizontal scaling kapasitas cache tanpa batasan praktis, menjadikannya solusi yang layak bahkan untuk aplikasi dengan volume cache yang sangat besar.

Monitoring dengan Mission Control Jobs

Mission Control Jobs menyediakan dashboard web untuk memeriksa dan mengelola job Solid Queue secara visual. Dashboard ini menampilkan informasi tentang workers, queues, serta status job (in progress, finished, blocked, failed) melalui Rails engine yang di-mount ke dalam aplikasi.

ruby
# config/routes.rb
Rails.application.routes.draw do
  mount MissionControl::Jobs::Engine, at: "/jobs"
end

# Gemfile
gem "mission_control-jobs", ">= 1.0.1"

Mission Control juga menyediakan API konsol untuk melakukan operasi bulk pada failed jobs, yang sangat berguna dalam skenario kegagalan berskala besar:

ruby
# Rails console
ActiveJob.jobs.failed.where(job_class: "ApiSyncJob").retry_all
ActiveJob.jobs.failed.where(job_class: "BrokenJob").discard_all

Akses programatik ini sangat penting untuk menangani kegagalan job dalam jumlah besar tanpa harus mengklik satu per satu melalui antarmuka dashboard. Tim operasional dapat menyusun script otomatis untuk menangani pola kegagalan yang sudah dikenali, mempercepat waktu recovery, dan mengurangi beban kerja manual dalam pemeliharaan sistem.

Pertanyaan Interview Teknis yang Sering Diajukan

Sesi interview Rails 8 semakin banyak memfokuskan pembahasan pada Solid Stack. Berikut adalah pertanyaan-pertanyaan yang paling sering muncul beserta kedalaman jawaban yang diharapkan oleh pewawancara.

T: Bagaimana Solid Queue mencapai pemrosesan job secara konkuren tanpa Redis? Solid Queue memanfaatkan klausa SQL FOR UPDATE SKIP LOCKED yang memungkinkan beberapa worker melakukan polling pada tabel yang sama tanpa saling memblokir. Setiap worker mengunci sejumlah baris, memproses job pada baris tersebut, lalu menghapus record eksekusi. Worker lain secara otomatis melewati baris yang sudah terkunci dan mengklaim job yang berbeda. Mekanisme ini memberikan semantik antrian yang efisien langsung pada level database.

T: Masalah apa yang diselesaikan oleh fitur transactional enqueuing? Transactional enqueuing mencegah job dari tereksekusi sebelum transaksi database yang memicunya berhasil di-commit. Tanpa fitur ini, sebuah job dapat mereferensikan record yang sudah di-rollback, menyebabkan error ActiveRecord::RecordNotFound. Ini merupakan kelas bug yang sangat sulit direproduksi karena bersifat intermiten dan bergantung sepenuhnya pada timing eksekusi antara transaksi dan job processor.

T: Mengapa Solid Cache memilih strategi FIFO dibanding LRU? FIFO lebih sederhana untuk diimplementasikan pada database dan menghindari write amplification yang timbul dari pembaruan access timestamp pada setiap operasi baca. Trade-off ini dikompensasi oleh kapasitas SSD yang jauh lebih besar -- entri cache bertahan lebih lama, sehingga hit rate tetap tinggi meskipun strategi eviction secara teoretis kurang optimal. Dalam praktik, perbedaan hit rate antara FIFO dan LRU menjadi tidak signifikan ketika kapasitas penyimpanan tersedia dalam jumlah yang memadai.

T: Dalam kondisi seperti apa sebuah aplikasi tetap sebaiknya menggunakan Redis dibanding Solid Stack? Redis tetap menjadi pilihan yang lebih tepat untuk aplikasi yang memproses lebih dari 10.000 job per menit, beban kerja yang memerlukan pembacaan cache dengan latensi sub-millisecond, atau aplikasi yang sudah memanfaatkan Redis untuk keperluan lain seperti Pub/Sub, rate limiting, atau session storage. Solid Stack dirancang untuk menyederhanakan operasional, bukan untuk mengejar throughput puncak. Keputusan pemilihan harus selalu didasarkan pada profiling aktual terhadap beban kerja, bukan asumsi tentang skala.

Latihan pertanyaan-pertanyaan ini dan pertanyaan lainnya tersedia di modul ActiveJob & Background Jobs SharpSkill serta modul Caching Strategies.

Siap menguasai wawancara Ruby on Rails Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Kesimpulan

  • Solid Queue menggantikan antrian job berbasis Redis dengan solusi database-backed yang menggunakan FOR UPDATE SKIP LOCKED untuk pemrosesan konkuren yang efisien dan andal
  • Transactional enqueuing mengeliminasi race condition antara penulisan database dan eksekusi job -- sebuah jaminan yang tidak dapat diberikan oleh Redis
  • Kontrol concurrency bawaan, recurring jobs, dan integrasi Puma tersedia langsung dengan Solid Queue tanpa biaya tambahan maupun dependensi eksternal
  • Solid Cache menggunakan caching FIFO berbasis SSD dengan dukungan sharding dan enkripsi opsional, menghilangkan kebutuhan Memcached dan Redis dari tumpukan infrastruktur
  • Konfigurasi database terpisah untuk Solid Cache mencegah operasi cache churn dari mempengaruhi performa database utama aplikasi
  • Mission Control Jobs menyediakan monitoring production dan pengelolaan job secara bulk melalui dashboard web dan API konsol yang komprehensif
  • Untuk sebagian besar aplikasi Rails 8 di tahun 2026, Solid Stack merupakan pilihan default yang direkomendasikan -- Redis tetap menjadi opsi yang relevan hanya untuk kasus khusus high-throughput yang melebihi 10.000 job per menit

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Tag

#ruby-on-rails
#solid-queue
#solid-cache
#rails-8
#background-jobs
#caching
#interview

Bagikan

Artikel terkait