Docs · Building Features

Background Jobs

Solid Queue, the add-job skill, and scheduling recurring work.

Anything that shouldn't hold up a request, sending a batch of emails, processing a webhook, running cleanup, or a periodic task, runs as a background job. One Shot runs jobs on Solid Queue, which is already configured and needs no Redis: in production it runs in-process inside Puma, and in development and test it runs jobs inline or async automatically. perform_later just works from a fresh clone.

The fastest way to add one is the add-job skill in Claude Code.

Creating a job

bin/rails g job SendInvoiceReminder

This generates app/jobs/send_invoice_reminder_job.rb. Keep perform small and idempotent: Solid Queue may retry a job, so running it twice for the same input should be safe. Operate through account-scoped associations inside the job, the same rule as everywhere else in the app; never reach for a global scope like Invoice.find(id) when account.invoices.find(id) is available.

Enqueuing work

SendInvoiceReminderJob.perform_later(invoice.id)

Pass ids, not objects: by the time the job actually runs, the record you passed might have changed or been deleted, and an id forces the job to re-fetch current state rather than operate on a stale snapshot serialized at enqueue time. For work that should run later rather than now:

SendInvoiceReminderJob.set(wait: 1.hour).perform_later(invoice.id)

Recurring jobs

For work that should run on a schedule rather than in response to an event, add an entry to config/recurring.yml, using cron-style scheduling. Solid Queue reads this file and schedules the job itself; you don't need an external cron or a scheduler service.

Testing

Write spec/jobs/<name>_job_spec.rb, asserting the job's actual behavior with it performed inline (perform_enqueued_jobs or the equivalent for your test setup). Wherever the job is triggered from elsewhere in the app (a controller action, another job), assert on that trigger with have_enqueued_job; the test adapter for this is already configured, so no additional setup is needed.

Verify

bin/check should be green, including the new job spec.

Next

If the job needs to send an email, see Sending Email.