4.4 KiB
4.4 KiB
| title | aliases | tags | sources | created | updated | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Jobs Queue — Overview |
|
|
|
2026-05-15 | 2026-05-15 |
What It Is
Payload's Jobs Queue offloads long-running, expensive, or future-scheduled work from your main API server to separate compute resources.
Core Concepts
| Concept | Description |
|---|---|
| Task | A specific function with business logic (handler: async () => {}) |
| Workflow | Ordered grouping of tasks; retryable from the exact failure point |
| Job | A single instance of a task or workflow queued for execution |
| Queue | Named segment that groups jobs (e.g. emails, nightly) |
Use Cases
Non-blocking hooks
- Vector embeddings on document change
- Sending data to third-party APIs
- Triggering emails from customer actions
Scheduled actions (via waitUntil)
- Publish/unpublish posts at a future time
- Trial reminder emails after X days
Periodic sync (via cron)
- Nightly rebuild of frontend
- Off-peak third-party API sync
Offloading heavy compute
- Open-source embedding models (keep out of Next.js bundle via dynamic import)
- PDF generation, headless browser tasks
- Durable multi-step pipelines
How Jobs Flow
Define Task → Queue Job → Stored in DB → Run Job → Task executes → Complete/Retry
Scheduling is two-part: defining a schedule in config is passive; you must also actively execute handleSchedules to queue jobs.
Running Jobs — 4 Options
| Option | When to Use |
|---|---|
pnpm payload jobs:run --cron "* * * * *" |
Dedicated server (recommended — separate process) |
autoRun: [{ cron, queue }] |
Dedicated server (runs within Next.js, handles both scheduling + running) |
GET /api/payload-jobs/run?queue=emails |
Serverless (triggered by Vercel Cron, GitHub Actions) |
payload.jobs.run({ queue }) |
Manual / programmatic |
Scheduling Jobs — 3 Options
| Option | When to Use |
|---|---|
pnpm payload jobs:handle-schedules --cron "* * * * *" |
Dedicated server bin script |
GET /api/payload-jobs/handle-schedules?queue=emails |
Serverless |
autoRun (default — also calls handleSchedules) |
Dedicated server only |
Key Takeaways
- Scheduling ≠ Running — two separate independent steps; the
queuename must match between them - Jobs persist in DB between queuing and execution — track status, retries, errors there
autoRunis dual-purpose by default: it both queues scheduled jobs AND runs queued jobs; setdisableScheduling: trueto run only- Never use
autoRunon serverless (Vercel, Lambda) — use API endpoints + external cron instead - Avoid duplicate scheduling: don't use
handle-schedulesbin script ANDautoRunfor the same queue simultaneously - Dynamic imports in Task handlers keep large dependencies out of the main Next.js bundle
- Admin UI visibility:
payload-jobscollection is hidden by default — usejobsCollectionOverridesto expose for debugging
Common Pitfalls
// WRONG: schedule defined but never executed
export const EmailTask: TaskConfig = {
slug: 'sendEmail',
schedule: [{ cron: '0 8 * * *', queue: 'emails' }], // passive only!
handler: async () => { /* ... */ },
}
// Must add: bin script, API endpoint, OR autoRun
// WRONG: duplicate scheduling — both handle schedules for same queue
pnpm payload jobs:handle-schedules --cron "* * * * *"
// + autoRun without disableScheduling: true → duplicate jobs queued
// FIX: autoRun run-only mode
autoRun: [{ cron: '* * * * *', queue: 'emails', disableScheduling: true }]
Expose Jobs in Admin UI
jobs: {
jobsCollectionOverrides: ({ defaultJobsCollection }) => {
defaultJobsCollection.admin = { hidden: false }
return defaultJobsCollection
},
}
Related Articles
- wiki/payloadcms/jobs-queue-jobs — queuing from hooks,
waitUntil, job status schema, access control, cancellation - wiki/payloadcms/hooks — how to queue jobs from afterChange/afterOperation hooks
- wiki/payloadcms/configuration —
autoRunand bin script config inbuildConfig - wiki/payloadcms/production — deployment patterns for dedicated vs serverless workers