Skip to content

Getting started

This guide adds Job to a backend app, defines a task, enqueues a run, and reads the resulting status.

Terminal window
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.

A task is a named backend function. The payload must be JSON-serializable.

Terminal window
jobs.task("send-email", {
retry: {
attempts: 5,
},
}, async (payload, ctx) => {
await sendEmail(payload, ctx)
})

The task context contains run and attempt metadata:

Terminal window
jobs.task("index-document", {}, async (payload, ctx) => {
console.log(ctx.runId)
console.log(ctx.attempt)
console.log(ctx.maxAttempts)
})

Call enqueue from a route, another task, or a product integration.

Terminal window
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.

Use delaySeconds for short delays:

Terminal window
await jobs.enqueue("send-email", {
to: "user@example.com",
subject: "Reminder",
}, {
delaySeconds: 60,
})

Use runAt when the execution time is known:

Terminal window
const run = await jobs.enqueue("send-email", {
to: "user@example.com",
subject: "Trial ending soon",
}, {
runAt: "2026-06-01T09:00:00.000Z",
})
Terminal window
const current = await jobs.runs.get(run.runId)
return Response.json({
status: current?.status,
attempts: current?.attemptCount,
})

List recent failed runs for a task:

Terminal window
const failed = await jobs.runs.list({
taskName: "send-email",
status: "dead_lettered",
limit: 25,
})

Cancel a run that should stop executing:

Terminal window
await jobs.runs.cancel(run.runId)

Replay creates a new run with the previous payload:

Terminal window
await jobs.runs.replay(run.runId, {
reason: "manual replay",
})
  • 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.