Getting started
This guide adds Job to a backend app, defines a task, enqueues a run, and reads the resulting status.
Configure Job
Section titled “Configure Job”import { backend } from "@layeron/core"import { job } from "@layeron/modules"
const app = backend({ project: "acme-api",})
const jobs = job({ name: "background", namespace: "app", retry: { attempts: 3, backoff: "exponential", initialDelaySeconds: 5, maxDelaySeconds: 300, },})
app.use(jobs)The deployment plan includes a Job Product Worker, a Job state store, and an internal Queue Product delivery channel for waking the Job Worker.
Define a task
Section titled “Define a task”A task is a named backend function. The payload must be JSON-serializable.
jobs.task("send-email", { retry: { attempts: 5, },}, async (payload, ctx) => { await sendEmail(payload, ctx)})The task context contains run and attempt metadata:
jobs.task("index-document", {}, async (payload, ctx) => { console.log(ctx.runId) console.log(ctx.attempt) console.log(ctx.maxAttempts)})Enqueue work
Section titled “Enqueue work”Call enqueue from a route, another task, or a product integration.
app.post("/signup", async (request) => { const body = await request.json()
const run = await jobs.enqueue("send-email", { to: body.email, subject: "Welcome", }, { idempotencyKey: `welcome:${body.email}`, })
return Response.json({ queued: true, runId: run.runId, })})The returned runId is stable. Store it when the caller needs to inspect or
replay the work later.
Enqueue later
Section titled “Enqueue later”Use delaySeconds for short delays:
await jobs.enqueue("send-email", { to: "user@example.com", subject: "Reminder",}, { delaySeconds: 60,})Use runAt when the execution time is known:
const run = await jobs.enqueue("send-email", { to: "user@example.com", subject: "Trial ending soon",}, { runAt: "2026-06-01T09:00:00.000Z",})Inspect runs
Section titled “Inspect runs”const current = await jobs.runs.get(run.runId)
return Response.json({ status: current?.status, attempts: current?.attemptCount,})List recent failed runs for a task:
const failed = await jobs.runs.list({ taskName: "send-email", status: "dead_lettered", limit: 25,})Cancel and replay
Section titled “Cancel and replay”Cancel a run that should stop executing:
await jobs.runs.cancel(run.runId)Replay creates a new run with the previous payload:
await jobs.runs.replay(run.runId, { reason: "manual replay",})Next Steps
Section titled “Next Steps”- Execution model: Understand tasks, runs, attempts, Queue-backed delivery, and idempotency.
- Job types: Choose one-off, delayed, retrying, managed run, or webhook delivery jobs.
- Retries and failures: Configure retry defaults, task overrides, failure behavior, replay, and cancellation.
- Delays and scheduling: Use immediate runs,
delaySeconds,runAt, delayed replay, and cancellation. - Examples: Adapt common background task patterns.
- API reference: Review Job options, retry settings, queue settings, and result contracts.