Shaperail includes a Redis-backed background job queue with priority levels, automatic retries, and a dead letter queue for failed jobs.

Declaring jobs on endpoints

Add a jobs array to any endpoint in your resource YAML. Each entry is the name of a registered job handler.

endpoints:
  create:
    method: POST
    path: /users
    auth: [admin]
    input: [email, name, role, org_id]
    jobs: [send_welcome_email]

When the endpoint completes successfully, each listed job is enqueued automatically with the created record as the payload.

Priority levels

Every job has a priority. Each level maps to a separate Redis list so the worker always processes higher-priority jobs first.

Priority Redis key Use case
critical shaperail:jobs:queue:critical Payment processing, security alerts
high shaperail:jobs:queue:high Transactional email, webhooks
normal shaperail:jobs:queue:normal Welcome emails, notifications
low shaperail:jobs:queue:low Analytics, cleanup tasks

The worker polls queues in strict priority order: critical, high, normal, low. A job from a lower queue is only picked up when all higher queues are empty.

Jobs declared via jobs: on an endpoint default to normal priority.

Job lifecycle

Every job moves through a fixed set of states:

pending --> running --> completed
                  \--> failed --> (retry) --> pending
                           \--> dead letter queue
  • pending – enqueued and waiting for the worker.
  • running – picked up by the worker; handler is executing.
  • completed – handler returned success.
  • failed – handler returned an error or the job timed out.

Job metadata is stored in a Redis hash at shaperail:jobs:meta:{job_id} and expires after 7 days.

Retry behavior

Failed jobs are retried with exponential backoff. The delay before each retry is 2^attempt seconds:

Attempt Backoff
1 2s
2 4s
3 8s

The default max_retries is 3. You can override it when enqueuing with custom options:

queue.enqueue_with_options(
    "send_welcome_email",
    payload,
    JobPriority::Normal,
    5,   // max_retries
    300, // timeout_secs
).await?;

If a retry is scheduled, the job status returns to pending and is pushed back onto the same priority queue.

Dead letter queue

Jobs that exhaust all retries are moved to the dead letter queue at shaperail:jobs:dead. Each dead letter entry records:

  • job ID and name
  • original payload
  • final error message
  • total attempts
  • timestamp of final failure

Once a job enters the dead letter queue its status is permanently set to failed.

Job timeout

Each job has a configurable timeout. If the handler does not return within the timeout window, the job is treated as failed and follows the normal retry or dead letter path.

Setting Default
timeout_secs 300 (5 minutes)

Monitoring

Check the status of a specific job:

shaperail jobs:status <job_id>

This reads the metadata hash at shaperail:jobs:meta:{job_id} and prints the current status, attempt count, and last error if any.

Redis key reference

Key pattern Type Contents
shaperail:jobs:queue:{priority} List Serialized job envelopes
shaperail:jobs:meta:{job_id} Hash Job status, attempt count, timestamps
shaperail:jobs:dead List Dead letter entries

Back to top

Shaperail documentation lives in the same repository as the framework so every release has versioned instructions.

This site uses Just the Docs, a documentation theme for Jekyll.