Need help with jesque?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

589 Stars 125 Forks Apache License 2.0 491 Commits 29 Opened issues


An implementation of Resque in Java.

Services available


Need anything else?

Contributors list


Build Status Coverage Status License Apache 2.0 Maven Central

Jesque is an implementation of Resque in Java. It is fully-interoperable with the Ruby and Node.js (Coffee-Resque) implementations.

Jesque is a Maven project and depends on Jedis to connect to Redis, Jackson to map to/from JSON and SLF4J for logging.

The project contains a client implementation as well as a worker implementation that supports listeners.

NOTE: Jesque's delayed jobs implementation is not compatible with resque-scheduler

How do I use it?

Jesque requires Java 7+. Download the latest source at: Or, to use it in your Maven project, add it as a dependency:



// Configuration
final Config config = new ConfigBuilder().build();

// Add a job to the queue final Job job = new Job("TestAction", new Object[]{ 1, 2.3, true, "test", Arrays.asList("inner", 4.5)}); final Client client = new ClientImpl(config); client.enqueue("foo", job); client.end();

// Start a worker to run jobs from the queue final Worker worker = new WorkerImpl(config, Arrays.asList("foo"), new MapBasedJobFactory(map(entry("TestAction", TestAction.class))));

final Thread workerThread = new Thread(worker); workerThread.start();

// Enqueue more jobs, etc.

// Shutdown the worker when finished worker.end(true); try { workerThread.join(); } catch (Exception e){ e.printStackTrace(); }

If enqueueing multiple jobs at the same time, there is

client.batchEnqueue(String queue, List jobs)
which does it in an optimized way.

Delayed jobs

Delayed jobs can be executed at sometime in the future. ```java final long delay = 10; // in seconds final long future = System.currentTimeMillis() + (delay * 1000); // timestamp

client.delayedEnqueue("fooDelay", job, future); ```

Recurring Jobs

Recurring jobs can start at a specific time and execute at specified intervals. ```java final long delay = 10; // in seconds final long future = System.currentTimeMillis() + (delay * 1000); // timestamp final long frequency = 60; // in seconds

client.recurringEnqueue("fooRecur", job, future, (frequency * 1000)); ```

Cancelling jobs

Delayed and recurring jobs can be cancelled.

client.removeDelayedEnqueue("fooDelay", job);
client.removeRecurringEnqueue("fooRecur", job);

Using a ClientPool

is useful in multi threaded apps,
final Client jesqueClientPool = new ClientPoolImpl(config, PoolUtils.createJedisPool(config));
jesqueClientPool.enqueue("foo", job);


You can execute custom callbacks during specific Worker events.

int myVar = 0;
worker.getWorkerEventEmitter().addListener(new WorkerListener(){
   public void onEvent(WorkerEvent event, Worker worker, String queue, Job job, 
                       Object runner, Object result, Throwable t) {
    if (runner instanceof TestAction) {
        ((TestAction) runner).setSomeVariable(myVar);
}, WorkerEvent.JOB_EXECUTE);

Available Worker Events

    Finished starting up and is about to start running.
    Polling the queue.
    Processing a Job.
    About to execute a materialized Job.
    Successfully executed a materialized Job.
    Caught an Exception during the execution of a materialized Job.
    Caught an Exception during normal operation.
    Finished running and is about to shutdown.

For more usage examples check the tests. The tests require that Redis is running on


Use the resque-web application to see the status of your jobs and workers or, if you prefer Java, try Jesque-Web.

Redis Configuration

As mentioned Jesque depends on Jedis to connect to Redis.

You can configure Jesque to connect to Redis given a URL in a system property (as used in Heroku + RedisToGo) with the following snippet:

final ConfigBuilder configBuilder = new ConfigBuilder();
try {
  URI redisUrl = new URI(System.getProperty("REDIS_PROVIDER", ""));
  String redisHost = redisUrl.getHost();
  int redisPort = redisUrl.getPort();
  String redisUserInfo = redisUrl.getUserInfo();
  if (redisHost != null) {
  if (redisPort > -1) {
  if (redisUserInfo != null) {
} catch (URISyntaxException use) {
  // Handle error
final Config config =;

Design Decisions

  • I chose to implement the jobs as classes that implement
    . If the job requires arguments (most do), there must be a constructor that matches the supplied arguments. I felt this was the most flexible option and didn't require the jobs to inherit or implement a special Jesque class. Because of this, the jobs don't even need to know about Jesque at all. Furthermore, the client need not have the job's
    in its VM, it only needs to know the classname and all the parameters'
    es on its classpath. Only the workers realize the job and then run them.
  • I chose to use Jedis because:
    1. It is simple to use
    2. Fully supports Redis 2.0 and uses the new unified protocol
    3. No dependencies
  • I chose to use Jackson because:
    1. I was already familiar with it
    2. It performs great and does what it says on the tin
    3. No dependencies
  • I chose to use SLF4J because:
    1. It lets the application choose how to log
    2. No dependencies


If you are on Mac OS X, I highly recommend using the fantasic Homebrew package manager. It makes installing and maintaining libraries, tools and applications a cinch. E.g.:

brew install redis
brew install git
brew install maven

Boom! Ready to go!


Copyright 2020 Greg Haines

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.