Short reference on how to quickly debug the vanilla Rails job adapters.
Queue Adapters by Environment
| Environment | Adapter | Jobs Run In | Worker Needed? |
|---|---|---|---|
| development | :async |
Rails server process | No |
| test | :test |
Not executed (stored) | No |
| production | :solid_queue |
Separate worker | Yes (bin/jobs) |
Development (:async)
Jobs run in background threads ( Concurrent Ruby ThreadPoolExecutor Show archive.org snapshot ) within the process that called the job.
- Jobs execute immediately in a background thread within
bin/rails sand write to the server logs. -
bin/jobsdoes nothing in development, jobs already run in-process via:async. - Scripts and rake tasks log go to
log/development.log
Watch out for this within the Rails or development logs:
Enqueued HelloJob (Job ID: xxx) to Async(asap)
Performing HelloJob (Job ID: xxx)
Performed HelloJob (Job ID: xxx) in 3.5s
For debugging, add logging or run synchronously to add a debugger:
class HelloJob
def perform
puts "Hello" # → stdout of calling process (server or script terminal)
Rails.logger.info "Hello" # → log/development.log (always)
debugger # → Will halt unless your script terminates to early
end
end
- Use
tail -f log/development.logto se the logs. - Use to filter for all ActiveJob logs:
tail -f log/development.log | grep '\[ActiveJob\]'. - Debugging should work independently of
perform_noworperform_later.
Caution
As soon as the main thread stops, your job will be killed as well.
Production (:solid_queue)
- Jobs persist to
solid_queue_*tables. - Requires
bin/jobsworker running. - You can also check
/log/production.log.
# Check pending jobs
SolidQueue::ReadyExecution.count
# Check failed jobs
SolidQueue::FailedExecution.last&.error
# Find specific job
SolidQueue::Job.where(class_name: 'HelloJob').last
Test (:test)
Jobs are not executed and only stored for assertions.
- For system tests you can check
/log/test.log.
assert_enqueued_with(job: HelloJob, args: [membership])
# Or execute all queued jobs
perform_enqueued_jobs do
HelloJob.perform_later('matthew')
assert_performed_jobs 1
end
Further Reading
-
Concurrent Ruby ThreadPoolExecutor
Show archive.org snapshot
: The thread pool backing
:async - Rails AsyncAdapter source Show archive.org snapshot : How Rails wraps Concurrent Ruby
- Solid Queue Show archive.org snapshot : The production queue backend
Posted by Felix Eschey to makandra dev (2025-12-04 15:54)