GoodJob
PostgreSQL-backed ActiveJob backend for Ruby on Rails — runs background jobs in the same database as your application using PostgreSQL's advisory locks for concurrency control. GoodJob features: LISTEN/NOTIFY for instant job pickup (no polling), cron-like scheduled jobs (GoodJob::Cron), concurrency control (limit max concurrent jobs per queue or globally), job priority (0-100 integer), retry with exponential backoff, and a built-in web dashboard (GoodJob::Engine). Designed as a simpler alternative to Sidekiq that requires no Redis — runs in same Rails process, same PostgreSQL database. Ideal for applications already on PostgreSQL that want background jobs without additional infrastructure.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
GoodJob stores job arguments as JSON in PostgreSQL — never include sensitive agent credentials in job arguments; pass IDs and fetch credentials at execution time. Protect GoodJob dashboard from unauthorized access in production. Job table may accumulate sensitive agent data in serialized arguments; implement retention policy.
⚡ Reliability
Best When
You're building a Rails agent app on PostgreSQL that needs background jobs without adding Redis to your infrastructure — GoodJob gives you reliable async processing with just your existing database.
Avoid When
You need millions of jobs per day, you're not on PostgreSQL, or you need a cross-service job queue shared between multiple Rails applications.
Use Cases
- • Background agent task execution without Redis — GoodJob processes agent background jobs using existing PostgreSQL database; no Redis cluster required; agents enqueue tasks via AgentJob.perform_later(agent_id) using standard ActiveJob API
- • Scheduled agent report generation — GoodJob cron config { 'daily_agent_report' => { cron: '0 8 * * *', class: 'AgentReportJob' } } runs daily agent analytics without separate cron infrastructure
- • Concurrency-limited agent API calls — GoodJob concurrency control limits to 3 concurrent external API calls per agent; prevents rate limit violations in agent tool execution jobs
- • Agent job monitoring dashboard — GoodJob::Engine mounted at /jobs provides visual dashboard showing queued, running, failed, and completed agent jobs with retry UI
- • Transactional agent job enqueuing — GoodJob enqueues jobs within same PostgreSQL transaction as model saves; agent config update and job enqueue either both succeed or both rollback — impossible to miss a job
Not For
- • High-throughput job processing — GoodJob handles tens of thousands of jobs/day well but not millions; for high-volume agent job queues (100k+/day), Sidekiq's Redis backend with threading handles more throughput
- • Non-PostgreSQL databases — GoodJob requires PostgreSQL for advisory locks and LISTEN/NOTIFY; MySQL or SQLite agent apps must use Sidekiq, Resque, or DelayedJob
- • Cross-service job queues — GoodJob stores jobs in application database; for agent job queues shared across multiple services, use Sidekiq with Redis or cloud-native queues (SQS, Pub/Sub)
Interface
Authentication
No external auth — uses application's PostgreSQL connection. Dashboard (/jobs) should be protected with HTTP basic auth or application authentication in production.
Pricing
GoodJob is MIT licensed, maintained by Ben Sheldon. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ Execution mode must match deployment — GoodJob.config.execution_mode :async runs jobs in web process threads (Puma); :external requires separate GoodJob worker process; :inline runs synchronously (test mode); wrong mode in production causes agent jobs to never execute or blocks Puma threads
- ⚠ Database connection pool must accommodate GoodJob threads — GoodJob uses database_tasks: GoodJob.configuration.max_threads threads; if Rails DB pool (pool: 5 in database.yml) is smaller than GoodJob threads + Puma threads, agent jobs cause ActiveRecord::ConnectionTimeoutError
- ⚠ Transactional job enqueue can cause double-enqueue — if agent controller enqueues job inside transaction that retries on deadlock, job can be enqueued twice; use GoodJob concurrency key (good_job_uniqueness_id) to prevent duplicate processing of same agent task
- ⚠ Dashboard requires explicit route mounting — GoodJob::Engine must be mounted in routes.rb: mount GoodJob::Engine => '/good_job'; without mounting, dashboard is inaccessible and 404s; secure route with authenticate block in production to prevent unauthorized agent job visibility
- ⚠ Cron jobs require primary process awareness — GoodJob cron runs in only one process; in multi-process deployments, use GoodJob.configuration.enable_cron = true on designated primary process only; multiple processes running cron causes duplicate scheduled agent job execution
- ⚠ Discarded jobs don't retry by default — GoodJob discards jobs after executions_count exceeds retry_on limits; discarded agent jobs are preserved in DB but not retried; check GoodJob::Job.discarded scope for failed agent jobs and use job.reschedule to retry manually
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for GoodJob.
Scores are editorial opinions as of 2026-03-06.