Skip to main content

Jobs

Jobs are first-class values created with createJob. They carry their name, input schema, handler, and optional hooks as a single object.

createJob

import { createJob } from "@repo/queue";
import { z } from "zod";

export const sendEmailsJob = createJob("send-emails", {
input: z.object({
email: z.string().email(),
subject: z.string(),
body: z.string(),
}),
handler: async ({ email, subject, body }, ctx) => {
// payload is fully typed from the input schema
},
});

Parameters

FieldTypeDescription
namestringUnique job identifier (first argument)
inputStandardSchemaV1Schema defining the payload shape (Zod, Valibot, etc.)
handler(payload, ctx?) => Awaitable<TResult>Function that processes the job
hooksJobHooksOptional lifecycle hooks

Payload Typing

The payload argument in handler is inferred from the input schema. No manual type annotations needed -- the schema is the single source of truth for both runtime validation and TypeScript types.

Context (BaseJobCtx)

The second argument to handler provides execution context:

interface BaseJobCtx {
jobId: string;
queue: string;
attempt: number; // 1-based
maxAttempts?: number;
signal: AbortSignal;
meta?: Record<string, unknown>;
session?: Session; // auth session from dispatch time
log: Logger;
}

Hooks

Hooks run after the handler completes (or fails). All hooks are optional.

export const sendEmailsJob = createJob("send-emails", {
input: z.object({ /* ... */ }),
handler: async (payload, ctx) => { /* ... */ },
hooks: {
onError: (err, payload, ctx) => {
// called on every failed attempt
},
onFailed: (err, payload, ctx) => {
// called only on the final attempt (all retries exhausted)
},
onSuccess: (result, payload, ctx) => {
// called when handler returns successfully
},
},
});

Hook Signatures

interface JobHooks<TPayload, TResult, TCtx> {
onError?: (err: TResult, payload: TPayload, ctx: TCtx) => Awaitable<void>;
onFailed?: (err: TResult, payload: TPayload, ctx: TCtx) => Awaitable<void>;
onSuccess?: (result: TResult, payload: TPayload, ctx: TCtx) => Awaitable<void>;
}
  • onError -- fires on every failed attempt, including retries
  • onFailed -- fires only when attempt >= maxAttempts (final failure)
  • onSuccess -- fires when the handler resolves without throwing

Hooks can also be defined globally on the runtime. See Runtime.