Library / SDK
resque/resque avatar
resque/resque

Resque: queue lists, polling workers, and JSON payloads

Resque is a Redis-backed Ruby library for creating background jobs, placing them on multiple queues, and processing them later.

9,467 stars1,660 forksRubyMIT

At a glance

What is it?
Resque turns any Ruby class that responds to perform into a Redis backed job. What you get is ordering by queue name, a polling rake task with no job ceiling, and a separate Sinatra app for watching workers. Where it stops is as informative as where it works.
Who is it for?
Resque fits a Rails or plain Ruby app that already runs Redis and is happy with queue level ordering plus a separate monitoring app. It does not fit teams that need numeric priorities, a bound on jobs per worker, or Ruby below 3.2.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 12 days ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • resque/resque9,467 ★ · -6
Star history
Repository2026-09-222026-11-14
resque/resque9.5k9.5k

-6 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

A queue list, not a number, decides what runs first

Resque has no numeric priority. Ordering comes from the sequence of queue names handed to a worker, which the project calls the queue list:

code
$ QUEUES=critical,archive,high,low rake resque:work

A worker checks the first name until it finds nothing, processes what it takes, and only then moves to the next name, returning to the head of the list after every job it takes from a later one.

Two things it cannot do follow from that. It cannot rank a job above another job, so two jobs both sitting on critical are taken in arrival order with no way to move one ahead. And a queue named last in the list waits longest: continuous traffic on the first name keeps the later ones from being reached at all, so appending bulk work to a list only helps if the head of the list goes idle regularly. The project's own layout leans on that shape, running a general list on one class of machine and pulling archive out onto a machine of its own with a single queue command.

A payload is JSON, so arguments have to be rebuildable

A job is a class name, an argument list, and one perform call. Queues store jobs as simple JSON packages, and enqueuing passes the class plus arguments:

ruby
class Repository
  def async_create_archive(branch)
    Resque.enqueue(Archive, self.id, branch)
  end
end

The queue is set by a class instance variable:

ruby
class Archive
  @queue = :file_serve

  def self.perform(repo_id, branch = 'master')
    repo = Repository.find(repo_id)
    repo.create_archive(branch)
  end
end

A worker pulls the package back and dispatches it in two lines:

ruby
klass, args = Resque.reserve(:file_serve)
klass.perform(*args) if klass.respond_to? :perform

That dispatch shape sets the limits. The argument list has to survive a JSON round trip, which is why the example hands over repo_id and a branch string and re-finds the record inside the worker instead of passing a loaded object. And the worker has to be able to load the class at all, which is what the opt-in require of your app in the Rakefile exists for.

The worker loop never finishes on its own

Workers are rake tasks meant to run until something stops them, and the loop the project prints is short:

ruby
start
loop do
  if job = reserve
    job.process
  else
    sleep 5 # Polling frequency = 5
  end
end
shutdown

Three consequences matter when you size a deployment. An idle worker does not block on a pop; it sleeps five seconds and asks again, so every dormant worker keeps generating Redis traffic on that cadence, and a fleet of workers multiplies the polls. The loop as printed carries no exit condition, no maximum job count and no time limit, so a worker stays resident for as long as its process lives. The list of worker properties also says workers are resilient to memory bloat and leaks. Shutdown is left to the operator, and for several workers the guidance is blunt:

code
$ COUNT=2 QUEUE=* rake resque:workers

Each of those runs in its own process, and the README says hitting ctrl-c should be sufficient to stop them all.

A splat is alphabetical, and negation cannot express an order

A splat tells a worker to take everything, including queues created on the fly after startup:

code
$ QUEUE=* rake resque:work

The catch sits in the next line of the documentation: queues are processed in alphabetical order. A splat only worker has ordering, but it is ordering by name rather than by importance, and it is decided at the moment names are compared, so a queue added to your application later lands wherever the alphabet puts it. Named queues can be floated above the splat:

code
# QUEUE=critical,* rake resque:work

Negation subtracts from the splat, by exact name or by prefix:

code
$ QUEUE=*,!low rake resque:work
code
$ QUEUE=*,!file_* rake resque:work

What the negation form cannot do is express an order. The documentation states that the order in which negated queues are listed does not matter, so QUEUE=*,!file_* and QUEUE=!file_*,* behave the same. A worker that must handle the archive queue alone therefore needs its own command, and every distinct set of queues means another start line to keep track of across every machine.

Version floors strand older Ruby and Rails stacks on the 2.x line

The install documentation sets high floors. Resque requires Ruby 3.2.0 or newer, lists 3.2, 3.3, 3.4 and 4.0 as supported, and pairs that with Redis server 4.0+, redis gem 4.0+, Rack 2.x or 3.x, and Rails 7.2+ for the ActiveJob integration. The 3.0 notes repeat the shape: Ruby 3.0+ with Ruby 2.x dropped, redis gem 4.0+ tested against 4.x and 5.x, Sinatra 2.0+ with either Rack line, and continued Rails 7.2 and ActiveJob compatibility. Releases shipped recently are 3.2.0 on 2026-10-16, 3.1.0 on 2026-09-16 and 3.0.3 on 2026-09-10, so the 3.x line is where fixes land.

What that rules out is specific. An app on Ruby 3.1, or on a Rails release older than 7.2, falls outside the current support list. A Redis server below 4.0 sits outside the stated range. The single sentence offered for older stacks is that if you need Ruby 2.x support, use Resque 2.x.

Rails workers boot into different configuration than the web app

Under Rails the worker process is configured separately, through the resque:setup task. Three requires in the Rakefile set that up:

ruby
require 'resque'
require 'resque/tasks'
require 'your/app' # Include this line if you want your workers to have access to your application

The third line decides whether your job classes exist inside the worker, and its own comment marks it optional. Rather than editing the shipped task, Rails apps override it:

ruby
task "resque:setup" => :environment do
  Grit::Git.git_timeout = 10.minutes
end

The remark that follows explains the intent: the web app should not carry a ten minute git timeout, but in the Resque workers it is fine. That split is the mechanism and the hazard at once. A worker boots into different configuration from the process that enqueued the job, so model loading, credentials, timeouts and anything else a job depends on has to be established inside the setup task or the require list. Configuration the web process applies at runtime is not inherited, and a job that relies on it fails on the worker side while the request that enqueued it reported success.

Monitoring is a standalone Sinatra app, and supervision is left to you

Resque is three parts: a Ruby library for creating, querying and processing jobs, a rake task that starts a worker, and a Sinatra app for monitoring queues, jobs and workers. The front end reports what workers are doing, what workers are not doing, which queues exist, what is in them, general usage stats, and failures. The repository root carries a config.ru for that Rack app, next to bin/, log/ and a docs/ directory.

Every number it shows is read from the same Redis the workers reserve from, and the only condition named for a worker is network access to the Redis server, with workers able to run anywhere holding that. Queues are persistent and provide visibility into their contents, so a backlog shows up as a growing list rather than as an error, and a worker that never registered shows up as absence rather than as a failure.

For process supervision, the repository ships example directories for god and monit alongside examples/async_helper.rb, examples/instance.rb, examples/resque_config.rb and examples/simple.rb.

Editorial conclusion

Resque fits a Rails or plain Ruby app that already runs Redis and is happy with queue level ordering plus a separate monitoring app. It does not fit teams that need numeric priorities, a bound on jobs per worker, or Ruby below 3.2. Before adopting, check the Ruby, Redis server, redis gem, Rack and Rails versions your app already pins, then read every worker start command for the queue list it hardcodes.

Frequently asked questions

What is a resque?

A Redis-backed library for creating background jobs, placing them on multiple queues, and processing them later. It is pronounced like the word rescue, and it ships as three parts: the library, a Rake task for starting a worker, and a Sinatra app for monitoring.

Is it rescue or resque?

The name is Resque, spelled with a que, and the project states it is pronounced like rescue. The homepage is http://resque.github.io/ and the source lives at resque/resque under the MIT license.

What is a resque worker?

A Rake task that runs forever: it starts, reserves a job, processes it, and when it finds none sleeps 5 before polling again. One worker is started with QUEUE=file_serve rake resque:work, and several at once with COUNT=2 QUEUE=* rake resque:workers, each in its own process.

resque vs sidekiq

The project's own documentation does not compare Resque with Sidekiq. What it does fix is that Resque has no numeric priorities, uses the order of the queue list instead, stores jobs as simple JSON packages, and was heavily inspired by DelayedJob.

resque alternative

The one predecessor named is DelayedJob, which the project says Resque was heavily inspired by. Beyond that the documentation does not list replacement libraries, and points instead at its own three parts, including the Sinatra app for monitoring queues, jobs and workers.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. resque/resque on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/resque-resque.svg)](https://hysenlabs.com/projects/resque-resque)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/resque-resque.svg)](https://hysenlabs.com/projects/resque-resque)

Was this useful?