Overview
Move slow, failure-prone work off the request path into jobs with explicit success and failure handling.
Idempotency
job
async function sendInvoice(id: string) {
const job = await db.job.findUnique({ where: { key: id } });
if (job?.done) return; // idempotent
await email.send(id);
await db.job.update({ where: { key: id }, data: { done: true } });
}Retries
Use exponential backoff with a max attempt count; route permanent failures to a dead-letter queue for inspection.