Fully-functional Admin UI

Admininster and monitor all your Odd Job runners from one admin dashboard. View jobs, cancel jobs, manually retry failed jobs, and more.

Read more

Schedule jobs for future

Get cron-like functionality by scheduling jobs for future execution. Deliver post-transaction emails, implement delayed deletion, and more.

Read more

Automatically retry failed jobs

Odd Jobs will automatically retry your job if it throws an unhandled exception. It will keep retrying cfgDefaultMaxAttempts times.

Read more

Structured logging

Logs are emitted as LogEvents to allow structured logging in JSON / XML. Visualize your job queue's performance using tools that you already know, like Kibana, Grafana, etc.

Read more


Uses Postgres' LISTEN / NOTIFY to get immediately notified about newly queued jobs. Uses Haskell's lightweight threads to execute mutliple jobs in the same OS process.

Read more

Concurrency control

Control the number of concurrent jobs picked-up by each Odd Jobs runner to avoid overwhelming your machine. Use dynamic concurrency control to keep picking jobs till machine's resource-limits allow.

Read more

Lifecycle hooks

Use lifecycle hooks to run a custom function every time a job succeeds, fails, or times-out. Use it to push failure notifications to error monitoring systems, such as Airbrake or Sentry.

Read more

Built-in CLI

OddJobs.Cli helps you build a standalone executable for your Odd Jobs runner that can be started as a background daemon and shutdown gracefully.

Read more

Highly configurable. Yet easy to get started.

While Odd Job's Config has 15 (and counting) config params, you can get started easily with sensible default by using the ConfigBuilder.

Get started →

Frequently asked questions

Why build yet another job queue?

Short answer: We couldn't find anything that fit our needs.

Long answer: Read our Utlimate guide on Haskell Job Queues to get an overview of the various packages that solve a similar problem, what works, and what doesn't. It can help you evaluate whether Odd Jobs is the right choice for your needs, or not.

Why is this specific to PostgreSQL? What about Redis?

Since Odd Jobs was built to "scratch our own itch" at Vacation Labs, we picked the datastore that we use in production, i.e. PostgreSQL.

Redis is also a fine data-store for a queue, and we are open to pull-requests that would like to evolve Odd Jobs to work with Redis, or even other RDBMs (eg. MySQL)

Isn't using an RDBMS as a queue a "bad idea"?

Not really. It depends on the ops/sec you expect from your queueing system. PostgreSQL has been used to process 10,000+ jobs per sec. Are your needs more than that? If not, it is strongly recommended to keep your production environment simple, and just use your existing PostgreSQL database as your queueing system.

The pros & cons are discussed at length in this note about storage backends for job-queues.