Migrate from DelayedJob to GoodJob

2023-10-13 4 min

Recently, I decided to replace DelayedJob by GoodJob. There was no major performance reason but the fact of DelayedJob’s low maintenance and GoodJob’s comprehensive documentation convinced me to give it a try.

After some days of testing I decided to switch to Goodjob. Here are the key factors that convinced me:

Anyway, the focus of the article it’s not drawing comparisons between the two libraries (everyone can have their own reasons) but rather on providing some guidance on the migration from DelayedJob to GoodJob and, more broadly, transitioning between two background workers.

💡 This migration guide is based on the use of the ActiveJob interface, which actually makes the migration much easier.

The following guide has been elaborated as a checklist in two steps:

  1. Both workers run side by side
  2. Decommissioning DelayedJob

Please bear in mind that this isn’t an exhaustive manual but rather a set of general guidelines. You’ll need to customize these recommendations to fit the specific nuances of your application.

Both workers run side by side

In this first step the goal is to setup GoodJob without removing DelayedJob. The key point here is to run both background workers side by side: GoodJob will handle new jobs, while DelayedJob will continue processing pending jobs until none remain.

Decommissioning DelayedJob

Once there are no pending jobs in DelayedJob, it’s time to proceed to take it out as follows.


And so far, the steps to follow to migrate from DelayedJob to GoodJob. It is not a complicated procedure because in this case both use the same storage database (Postgres) but a worker cannot be removed by simply unplugging it. It requires a series of steps to ensure that no pending work is lost during the switchover.

Another step I haven’t mentioned concerns the fine-tuning of the new worker engine. Perhaps instead of replacing DelayedJob with GoodJob in the first step, you’d rather keep working with DelayedJob and test GoodJob in production before taking it for granted. Just don’t replace config.active_job.queue_adapter in the first step. Leave it for later.

And that’s it. Now you have a better idea of how to migrate a worker engine. The steps are more or less similar even if you change the storage system (e.g. Redis).