Background job processing systems enable applications to offload time-consuming tasks (email sending, image processing, data exports, API calls) to separate worker processes that execute asynchronously from the main request-response cycle. These systems prevent user-facing operations from blocking on long-running work by placing jobs into persistent queues backed by Redis, PostgreSQL, RabbitMQ, or cloud services like AWS SQS. Understanding job queue architectures, retry strategies, priority scheduling, and monitoring patterns is essential for building scalable, resilient systems that handle millions of tasks daily while gracefully managing failures. A well-designed background job system transforms a slow, brittle application into one that feels fast and handles spikes in load without degradation β every modern web application processing significant workload relies on one.
What This Cheat Sheet Covers
This topic spans 15 focused tables and 160 indexed concepts, 143 flashcards. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: Job Queue Frameworks by Language
The ecosystem of job queue libraries spans every major backend language; choosing the right one determines your operational model, performance ceiling, and infrastructure requirements. Most frameworks offer a spectrum from Redis-backed in-memory speed to database-backed ACID guarantees β with managed cloud platforms now offering a third path requiring no broker infrastructure at all.
| Framework | Example | Description | |
|---|---|---|---|
class EmailJob include Sidekiq::Job def perform(user_id) User.find(user_id).send_welcome endendEmailJob.perform_async(123) | β’ Ruby's most popular background job processor β’ multi-threaded (handles many jobs per process), uses Redis for storage, supports retries and scheduled jobs β’ powers Shopify, GitHub, and thousands of Rails apps. | ||
const queue = new Queue('emails');await queue.add('send', { userId: 123, type: 'welcome'}); | β’ Node.js and Bun job queue built on Redis with priorities, rate limiting, delayed jobs, parent-child workflows, and events β’ successor to Bull with better TypeScript support and performance. | ||
def send_email(user_id): user = User.objects.get(id=user_id) user.send_welcome()send_email.delay(123) | β’ Python's distributed task queue standard β’ supports multiple brokers (RabbitMQ, Redis, SQS), result backends, periodic tasks with Celery Beat, and canvas workflows for complex orchestration. | ||
BackgroundJob.Enqueue(() => SendEmail(123));RecurringJob.AddOrUpdate( "cleanup", () => Cleanup(), Cron.Daily); | β’ .NET background job processor integrated with ASP.NET β’ uses SQL Server, PostgreSQL, or Redis for persistence, includes built-in dashboard, supports fire-and-forget, delayed, recurring, and continuation jobs. | ||
async def order_workflow(order_id): await charge_payment(order_id) await ship_order(order_id) await send_notification(order_id) | β’ Durable execution platform for workflows and long-running processes β’ uses event sourcing to capture state at every step, enabling automatic retries from exact failure point β’ handles multi-step sagas, human-in-the-loop, and distributed orchestration β’ supports Go, Java, Python, TypeScript, PHP. | ||
inngest.createFunction( { id: "send-email" }, { event: "user.created" }, async ({ event }) => { await sendEmail(event.data); }); | β’ Event-driven workflow platform for TypeScript/JavaScript β’ serverless-native with automatic retries, step functions, and durable execution β’ handles long-running workflows without managing infrastructure | ||
task("send-email", async (payload) => { await sendEmail(payload.userId);}); | β’ Open-source TypeScript background job platform with no timeouts β runs on long-lived compute, not serverless functions β’ automatic retries, real-time observability, elastic scaling, and support for AI/agent workflows β’ self-hostable or managed cloud. | ||
class SendEmailJob implements ShouldQueue { public function handle() { Mail::to($this->user)->send(...); }}SendEmailJob::dispatch($user); | β’ PHP/Laravel's built-in async job system supporting Redis, SQS, database, and Beanstalkd drivers β’ job chaining, batching, rate limiting, and graceful failure handling built in β’ monitored via Laravel Horizon (Redis dashboard). | ||
class EmailJob < ApplicationJob queue_as :emails def perform(user_id) User.find(user_id).send_email endendEmailJob.perform_later(123) | β’ Rails' built-in abstraction layer for background jobs β’ doesn't process jobs itself but provides unified API for Sidekiq, Solid Queue, GoodJob, Resque, Delayed Job, and others β’ enables adapter-agnostic job code. | ||
client := asynq.NewClient(...)task := asynq.NewTask("email:send", payload, asynq.MaxRetry(5))client.Enqueue(task) | β’ Go task queue backed by Redis β’ supports weighted priority queues, strict priority queues, unique tasks, periodic tasks, task aggregation, and Prometheus metrics β’ includes Asynqmon web UI and CLI. | ||
riverClient.InsertTx(ctx, tx, SendEmailArgs{UserID: user.ID}, nil) | β’ Go background job library backed by PostgreSQL β’ transactional enqueueing β job is committed in same DB transaction as your business logic, guaranteeing no lost jobs β’ no external services required beyond Postgres. | ||
BackgroundJob.enqueue( () -> myService.sendEmail(userId));BackgroundJob.scheduleRecurrently( Cron.daily(), () -> report()); | β’ Java distributed background job library; uses any existing database (Postgres, SQL Server, Oracle) as storage β’ simple lambda-based API, real-time dashboard, automatic retries, and carbon-aware scheduling (v8+). | ||
from rq import Queueq = Queue(connection=redis_conn)job = q.enqueue(send_email, 123) | β’ Lightweight Python job queue using Redis β’ simpler than Celery with fewer features; uses fork-based workers β’ includes dashboard via rq-dashboard; good for small to medium Python apps. | ||
class NotifyJob < ApplicationJob def perform(user_id) User.find(user_id).notify endendNotifyJob.perform_later(123) | β’ Rails Active Job adapter using PostgreSQL for storage β’ multithread, multi-process execution; includes web dashboard and cron-style recurring jobs β’ no Redis required; ACID guarantees for job atomicity. | ||
config/queue.ymldefault: workers: 3 queues: [default, mailers] | β’ Rails-official Active Job backend using SQLite or PostgreSQL β’ ships with Rails 8; designed for simpler deployments without Redis β’ supports priorities, recurring jobs, and concurrency controls. | ||
class EmailJob @queue = :emails def self.perform(user_id) User.find(user_id).send_email endendResque.enqueue(EmailJob, 123) | β’ Redis-backed Ruby library using forked processes instead of threads β’ simpler than Sidekiq but less efficient (one job per process) β’ includes web UI; largely superseded by Sidekiq in modern Rails apps. | ||
class WelcomeMailer handle_asynchronously :deliverend | β’ Rails background job system storing jobs in the database via ActiveRecord β’ single-threaded polling model; lower throughput than Redis-backed queues β’ no external dependencies; still used in smaller or legacy Rails apps. | ||
IJobDetail job = JobBuilder .Create<ReportJob>().Build();ITrigger trigger = TriggerBuilder .Create().WithCronSchedule( "0 0 3 * * ?").Build(); | β’ .NET job scheduling library for cron-style recurring jobs β’ stores schedules in SQL Server, PostgreSQL, or in-memory; thread pool execution with clustering support β’ often combined with Hangfire for full background processing. | ||
const queue = kue.createQueue();queue.create('email', { userId: 123}).save(); | β’ Node.js priority job queue backed by Redis with web UI β’ no longer actively maintained; BullMQ is the recommended replacement β’ still found in legacy Node apps. |