Client Area

Sidekiq Background Jobs for Rails on DomainIndia VPS

ByDomain India Team·DomainIndia Engineering
4 min read24 Apr 20263 views
# Sidekiq Background Jobs for Rails on DomainIndia VPS
TL;DR
Sidekiq runs Ruby background jobs using Redis as the queue — essential for any Rails app doing email sending, PDF generation, image processing, or webhooks. This guide covers installing Redis, configuring Sidekiq, systemd services, monitoring, and scaling on DomainIndia VPS.
## Why Sidekiq (not Solid Queue, DelayedJob, Resque)? Rails 8 ships with **Solid Queue** (DB-backed queue), which is great for simple workloads. But for anything serious, **Sidekiq** still wins:
QueueBackendThroughputBest for
Solid QueueDB (PostgreSQL)~1K jobs/minSimple Rails apps, <50 jobs/sec
SidekiqRedis~10K+ jobs/minProduction Rails, high throughput
DelayedJobDB~500/minLegacy apps
ResqueRedis~2K/minOlder alternative, less maintained
Sidekiq's multi-thread model + Redis backend make it 10× faster per process than DB-backed queues. It's the standard for production Rails. ## Architecture on DomainIndia VPS ``` [Rails web (Puma)] ──► enqueues job ──► [Redis] │ [Sidekiq worker 1] ◄──── picks jobs ─────┤ [Sidekiq worker 2] ◄──── picks jobs ─────┘ ``` - Rails web process (Puma) accepts HTTP, enqueues jobs - Redis holds the queue - Sidekiq worker processes pull jobs, run them - All three run as systemd services on the same VPS (or different VPS for scale) ## Step 1 — Install Redis On the VPS: ```bash # AlmaLinux sudo dnf install -y redis sudo systemctl enable --now redis # Ubuntu sudo apt install -y redis-server sudo systemctl enable --now redis-server redis-cli ping # → PONG ``` Enable persistence so queued jobs survive server restart: ```bash sudo sed -i 's/^appendonly no/appendonly yes/' /etc/redis/redis.conf sudo systemctl restart redis ``` ## Step 2 — Add Sidekiq to your Rails app `Gemfile`: ```ruby gem 'sidekiq', '~> 7.2' ``` ```bash bundle install ``` `config/initializers/sidekiq.rb`: ```ruby Sidekiq.configure_server do |config| config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') } end Sidekiq.configure_client do |config| config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') } end ``` `config/application.rb`: ```ruby config.active_job.queue_adapter = :sidekiq ``` ## Step 3 — Write a job `app/jobs/send_welcome_email_job.rb`: ```ruby class SendWelcomeEmailJob < ApplicationJob queue_as :default retry_on Net::SMTPError, wait: :exponentially_longer, attempts: 5 def perform(user_id) user = User.find(user_id) UserMailer.welcome(user).deliver_now end end ``` Enqueue: ```ruby SendWelcomeEmailJob.perform_later(user.id) ``` ## Step 4 — Systemd service for Sidekiq `/etc/systemd/system/sidekiq-yourapp.service`: ```ini [Unit] Description=Sidekiq for YourApp After=network.target redis.service postgresql.service [Service] Type=simple User=deploy Group=deploy WorkingDirectory=/home/deploy/rails_app Environment="RAILS_ENV=production" Environment="PATH=/home/deploy/.rbenv/shims:/usr/bin:/bin" ExecStart=/home/deploy/.rbenv/shims/bundle exec sidekiq -e production -C /home/deploy/rails_app/config/sidekiq.yml ExecReload=/bin/kill -TSTP $MAINPID Restart=on-failure RestartSec=5 # Graceful shutdown — let Sidekiq finish current jobs TimeoutStopSec=30 KillSignal=SIGTERM EnvironmentFile=-/home/deploy/rails_app/.env StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ``` `config/sidekiq.yml`: ```yaml :concurrency: 10 # threads per worker process :queues: - [critical, 3] # weight 3 — critical queue serviced 3× more - [default, 2] - [mailers, 1] - [low, 1] :timeout: 25 # jobs killed after 25s if still running when SIGTERM ``` Enable: ```bash sudo systemctl daemon-reload sudo systemctl enable --now sidekiq-yourapp sudo journalctl -u sidekiq-yourapp -f ``` ## Step 5 — Sidekiq web UI Mount the dashboard for monitoring: `config/routes.rb`: ```ruby require 'sidekiq/web' Rails.application.routes.draw do authenticate :user, ->(u) { u.admin? } do mount Sidekiq::Web => '/sidekiq' end # ... other routes end ``` Visit `https://yourcompany.com/sidekiq` — see queued, retried, scheduled, dead jobs. ## Job patterns ### Scheduled / delayed jobs ```ruby ReminderJob.set(wait: 1.hour).perform_later(booking_id) ReminderJob.set(wait_until: 2.days.from_now).perform_later(booking_id) ``` ### Recurring jobs (Sidekiq-cron or whenever gem) ```ruby # Gemfile gem 'sidekiq-cron' # config/schedule.yml cleanup_old_sessions: cron: "0 2 * * *" # 2 AM daily class: "CleanupOldSessionsJob" reindex_search: cron: "0 */6 * * *" # every 6 hours class: "ReindexSearchJob" ``` ### Unique jobs (prevent duplicates) ```ruby # Gemfile gem 'sidekiq-unique-jobs' class ImportantJob < ApplicationJob sidekiq_options lock: :until_executed def perform(id) # Only one concurrent execution per id end end ``` ## Scaling patterns **Single VPS, multiple workers:** Add more worker processes on the same VPS — 2–4 is typical before RAM becomes the limit. ``` /etc/systemd/system/[email protected] (templated service) ``` Start `[email protected]`, `@2.service` etc. **Multi-VPS (horizontal scale):** Put Redis on a dedicated VPS. Point all web + worker VPS at it: ``` REDIS_URL=redis://redis.internal.yourcompany.com:6379/0 ``` For HA Redis: Sentinel (free) or Redis Cloud (managed). ## Monitoring and alerts **Sidekiq stats endpoint:** ```ruby Sidekiq::Stats.new.enqueued # waiting to run Sidekiq::Stats.new.retry_size # failed, waiting retry Sidekiq::DeadSet.new.size # permanently failed ``` Expose as `/health/sidekiq` and alert when queue >1000 or dead >10. **Sidekiq Pro/Enterprise** (commercial): - Batches (run many jobs, callback when all done) - Rate limiting - Quiet time, reliable fetch, encryption $179/mo. Worth it if Sidekiq is mission-critical. ## Common pitfalls ## FAQ
Q Sidekiq or Solid Queue for a new Rails 8 app?

If you'll never exceed ~10 jobs/sec, Solid Queue is simpler (no Redis). For anything higher or existing Redis infrastructure, Sidekiq.

Q Can I run Sidekiq on shared hosting?

No — Sidekiq needs a long-running worker process. Shared hosting runs PHP/Ruby per-request only. VPS required.

Q How many workers on a 2 GB VPS?

Depends on your jobs. Typical Rails worker uses 200–400 MB RAM. 1 web + 1 Sidekiq process (10 threads) fits comfortably. For heavier jobs (PDF, image), 2 worker processes max on 2 GB.

Q What about Sidekiq + Heroku/Render?

Works the same way, but you pay per worker dyno. DomainIndia VPS is more cost-efficient — one 4 GB VPS covers what costs ₹5,000+/mo on PaaS.

Q Is Sidekiq safe for critical jobs (payments)?

Yes, with care. Set retry_on for transient errors, use idempotency keys (check "already processed" before calling payment API), use Sidekiq Pro's reliable fetch for crash safety.

Sidekiq + Rails + Redis runs beautifully on a DomainIndia VPS. Get started

Was this article helpful?

Your feedback helps us improve our documentation

Still need help? Submit a support ticket

Still need help?

Our support team can assist you directly.

Submit Ticket