Core Concepts
Graphile Worker RS is a PostgreSQL-backed job queue for Rust applications. The core mental model is:
- Your application describes work as typed tasks.
- It adds jobs for those tasks into PostgreSQL.
- A worker fetches runnable jobs, executes the matching task handler, and records the result back in PostgreSQL.
The database is the coordination point. Jobs, task metadata, queue state,
worker state, retry metadata, and scheduling data live in the Graphile Worker
schema, which defaults to graphile_worker.
The Main Pieces
Tasks
A task is the Rust type that defines what a job does. It implements
TaskHandler, provides a stable task identifier, accepts a serializable payload,
and contains the async run method for the work.
use graphile_worker::{IntoTaskHandlerResult, TaskHandler, WorkerContext};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct SendEmail {
to: String,
subject: String,
}
impl TaskHandler for SendEmail {
const IDENTIFIER: &'static str = "send_email";
async fn run(self, _ctx: WorkerContext) -> impl IntoTaskHandlerResult {
println!("Sending email to {}", self.to);
Ok::<(), String>(())
}
}
Register task handlers on WorkerOptions before starting the worker:
let worker = graphile_worker::WorkerOptions::default()
.define_job::<SendEmail>()
.pg_pool(pg_pool)
.init()
.await?;
For more detail, see Tasks and Payloads.
Jobs
A job is a stored request to run a task. It includes the task identifier, payload, state, and execution metadata. Job specifications can also carry options such as priority, retry behavior, scheduling information, and queue selection.
Jobs are stored in PostgreSQL, so application processes can enqueue work and
worker processes can execute it independently. WorkerUtils provides utility
operations for managing jobs, such as adding, removing, and rescheduling them.
Workers
A worker is the runtime process that polls PostgreSQL, locks runnable jobs, and
executes registered handlers with the configured concurrency. Graphile Worker RS
uses PostgreSQL features such as SKIP LOCKED for efficient job fetching and
LISTEN/NOTIFY for low-latency wakeups.
graphile_worker::WorkerOptions::default()
.concurrency(5)
.define_job::<SendEmail>()
.pg_pool(pg_pool)
.init()
.await?
.run()
.await?;
Workers also own lifecycle concerns such as graceful shutdown. Optional recovery settings can record worker heartbeats and recover jobs locked by workers that no longer heartbeat.
For more detail, see Worker Lifecycle and Architecture.
Scheduling
Scheduling determines when a job becomes runnable. A job can be available
immediately or scheduled for a later time. Graphile Worker RS also exposes cron
support through Cron and CronBuilder for recurring work.
Use scheduling when the time a job should run matters more than when it was created, such as sending a reminder later or running a daily report.
For more detail, see Scheduling Model.
Queues and Concurrency
Concurrency controls how many jobs a worker may process at once. Queues add coordination around groups of jobs. They are useful when some work must be serialized or separated from other work.
The database schema includes _private_job_queues, which tracks queue names for
serialized job execution. Worker configuration controls the amount of parallel
work a process can take on.
For more detail, see Queues and Concurrency.
Database Schema
Graphile Worker RS manages its own PostgreSQL schema and migrations. The default
schema name is graphile_worker, and the crate documentation identifies these
core tables:
_private_jobsstores job data, state, and execution metadata._private_taskstracks registered task types._private_job_queuesmanages queue names for serialized job execution._private_workerstracks active worker instances.
For more detail, see Database Schema.
How The Pieces Fit Together
In a typical application:
- Define one Rust type per task and implement
TaskHandler. - Configure a
WorkerOptionsvalue with a PostgreSQL pool and task definitions. - Initialize the worker so migrations and setup can run.
- Add jobs from application code or utilities.
- Run one or more worker processes to execute runnable jobs.
The important boundary is between tasks and jobs. A task is code compiled into your application. A job is data stored in PostgreSQL that says which task should run, with which payload, and under which execution rules.
Where To Go Next
Start with Architecture for the system-level view, then read Tasks and Payloads and Worker Lifecycle to understand the main programming model. After that, use Scheduling Model, Queues and Concurrency, and Database Schema for the specific behavior you need to configure or operate.